perm filename MUSIC.FAI[MUS,LCS]4 blob
sn#160182 filedate 1975-05-21 generic text, type T, neo UTF8
00100 TITLE MUSIC
00200 ;;;****** AS OF JAN. 12, 1971 *********
00300 ; XGP INIT ADDED JAN 1974
00400 ↓T←1
00500 T1←2
00600 T2←3
00700 T3←4
00800 A←5
00900 B ←6
01000 C←7
01100 D←10
01200 E←11
01300 F←12
01400 H←14
01500 OSP←13
01600 ↓P←15
01700 ↓FL←17
01800 NACS←←5
01900 NFACS←←4
02000 INSXR←←NFACS-1
02100 SSPCF←←10
02200 SDFLG←←20
02300 SNUMF←←40
02400 FIXFLG←←1000
02500 FLTFLG←←2000
02600 DF←←400000
02700 NUMFLG←←FIXFLG+FLTFLG
02800 SSPC2F←←4000
02900
03000 RFLG←←0 ;$$$%%&%$###""##$%$$$$$
03100 DECLBIT←←400
03200 RVBT←←400
03300 PRVBT←←11
03400 MULBIT←←1
03500 ADDBIT←←2
03600 FOOBIT←←100
03700 INSBIT←←40
03800 UGBIT←←4000
03900 FPARBT←←200
04000
04100 SRACBT←←10000
04200 SIACBT←←20000
04300 GPBIT←←FOOBIT ;NOT I OR X.
04400 FUNBIT←←40000
04500 SWVBT←←100000 ;DO NOT CHANGE ! SEE GFUNC.
04600 VRBLBT←←200000
04700 ;; RELOCATION AND FIXUP BITS .
04800 .FXBTS←←1
04900 LFXBTS←←2
05000 VRELBT←←14+1
05100 RRELBT←←4+1
05200 IRELBT←←10+1
05300 ;; FLAGS (RIGHT HALF):
05400 CSBRBT←←1
05500 SFOOBT←←10
05600 USBRBT←←2
05700 GFUNCF←←4
05800 EXTFLG←←40
05900 ARRFLG←←20
06000 RVFLG←←100
06100 RESTART←←200
06200 ;FLAGS (LEFT HALF).
06300 ERRFLG←←1
06400 MINFLG←←2
06500 SNUMF1←←4
06600 NOSTAR←←10
06700 DTFLG←←20
06800 ;; PARAMETER DESCRIPTOR BITS:
06900 FAOPAR←←1
07000 FDPARB←←4
07100 FDPARC←←5
07200
07300 COFF←←1000 ;PI CHANNEL OFF.
07400 CON←←2000
07500 DACHN←←100 ;PI CHANNEL 1.
07600
07700 LRFXBT←←200000 ;LEFT HALF REPLACEMENT FIXUP BIT.
07800 RRFXBT←←100000 ;RIGHT HALF.
07900 SWAPBT←←40000 ;SWAPPED FIXUP.
08000
08100 ;;;;; 5/74 DEFINE IOWD (A,B) <XWD -A,B-1>
08200 OPDEF EXP [0]
08300 OPDEF FIX [XWD 247000,0] ;FOR PDP10 ONLY. REMOVE WITH DDT FOR PDP6
08400 ;*********↑↑↑↑↑↑↑↑↑
08500 OPDEF OUTCHR [XWD 51040,0]
08600 ;;UUOSER: 0
08700 ;; MOVEM A,SAVEA#
08800 ;; HLRZ A,40
08900 ;; CAIL A,2000
09000 ;; JRST FIXER
09100 ;; MOVE A,SAVEA
09200 ;; JSR ERR1
09300 ;; JRSTF @UUOSER
09400
09500 BEGIN SAVER
09600 ; (INSERTED 11/3/69)
09700 ; TO DUMP CORE IMAGE
09800 ; CREATE A FILE OF THE CURRENT CORE IMAGE.
09900 ; PICK UP THE USER'S INPUT FILE NAME STORED
10000 ; IN DLK AND CREATE A FILE CALLED:
10100 ; "NAME.SAV"
10200 ; WHERE NAME IS THE INPUT FILE NAME.
10300 ;
10400 ; THE SWAP UU0 WILL BE USED WHICH CLOSES ALL
10500 ; ACTIVE DEVICES.
10600 ;
10700 ; ACCUMULATORS 0 AND T WILL BE CLOBBERED BY THIS
10800 ; ROUTINE. ALL OTHERS WILL BE SAVED AND RESTORED.
10900
11000 INTERNAL SAVER
11100
11200 ↑SAVER: 0
11300 MOVE 0,SCP ;BASE OF INPUT BUFFER
11400 HRRZ T,IBUF ;CURRENT BUFFER
11500 SUBI 0,-BUF1-1(T) ;DIFFERENCE
11600 MOVEM 0,PLIST+LPLIST-10
11700
11800 MOVEM 17,ACS+17 ;SAVE REGISTERS
11900 MOVEI 17,ACS
12000 BLT 17,ACS+16
12100
12200 SKIPN T,DLK ;INPUT FILE NAME
12300 MOVSI T,'SAV'
12400 MOVEM T,SWPTBL+1
12500
12600 MOVSI T,SWPTBL ;ADDR OF 5 WORD BLOCK IN LEFT PART OF T
12700 CALL T,[SIXBIT /SWAP/]
12800
12900 RETR: MOVE P,[XWD -10,PLIST+LPLIST-10] ;PICK UP ACCUM P
13000 MOVEI FL,RESTART ;RESTORE RESTART FLAG
13100 SOS RECCT ;BACK UP TO PREVIOUS INPUT RECORD.
13200 PUSHJ P,SETUP ;JUMP TO RESTORE FILES
13300 POP P,SCP
13400 MOVEI GO
13500 HRRM JOBSA
13600 MOVSI 17,ACS ;RESTORE REGISTERS
13700 BLT 17,17
13800 JRA 16,(16)
13900
14000 ACS: BLOCK 20 ;REGISTER SAVE AREA
14100 SWPTBL: SIXBIT /DSK/ ;DEVICE FOR SWAP
14200 0 ;FOR FILENAME
14300 SIXBIT /SAV/ ;FILENAME.SAV
14400 RETR ;CORE SIZE (0=USE WHAT YOU NEED)
14500 0 ;END OF LIST
14600
14700 BEND SAVER
00100 ;INPUT ROUTINE. CALL INITIALLY WITH PUSHJ P,SETUP
00200 ;WILL READIN DTA# AND FILE NAME. GET CHRS BY
00300 ;ILDB IBUF+1. NEXT BUFFER BY INPUT DT,0.
00400 ;;;EXTERNAL IFIX
00500 EXTERNAL SMPLS
00600 EXTERNAL READIN
00700
00800 TTY←←10
00900 DT←←11
01000 ADCHN←←12
01100 SETUP: CALL [SIXBIT /RESET/]
01200 SETUP1: INIT TTY,1
01300 SIXBIT /TTY/
01400 XWD TOB,TIB
01500 CALL [SIXBIT /EXIT/]; ERROR CONDITION
01600 MOVSI 400000
01700 ANDCAM TIBUF+1 ;MARK INPUT BUFFERS EMPTY.
01800 ANDCAM BUF1+1
01900 ANDCAM BUF2+1
02000 ANDCAM BUF3+1
02100 HRRI TIBUF+1 ;INIT. BUFFER POINTERS.
02200 MOVEM TIB
02300 HRRI TOBUF+1
02400 MOVEM TOB
02500 OUTPUT TTY,1; SEE THE HAPPY SYSTEM
02600 ;;COLGATE OUTPUT TTY,
02700 TRNE FL,RESTART ;ARE WE RESTARTINIG ?
02800 JRST SET4 ;YES.
02900 MOVEI IMS
03000 JSR TXTOUT; A LF/CR *
03100 ;; 5/74 INPUT TTY,0; THE DTA # AND NAME
03200 ;; SETZM DNAM
03300 ;; MOVE 2,[POINT 6,DNAM]
03400 ;; MOVEI T2,6
03500 ;;SET3: ILDB TIB+1
03600 ;; CAIN ":"
03700 ;; JRST SET4
03800 ;; SUBI 40
03900 ;; IDPB 2
04000 ;; SOJG T2,SET3
04100 ;*******↓↓↓↓↓ 5/74
04200 EXTERNAL FILBRK,DLK,ASTR
04300 INTERNAL DEV
04400 SETZM ASTR
04500 JSA 16,FILBRK
04600 MOVE T2,[SIXBIT/TTY/]
04700 SKIPN DLK
04800 MOVEM T2,DNAM
04900 ;******↑↑↑↑↑
05000 SET4: INIT DT,1
05100 DNAM:DEV: SIXBIT /DTA/
05200 XWD 0,IBUF ;NO OUPUT ON THIS DEVICE.
05300 JRST AER1
05400 MOVE [XWD 400000,BUF1+1] ;SET UP BUFFER
05500 MOVEM IBUF ;HEADER SO SYSTEM WILL USE OUR BUFFERS.
05600 MOVSI 700
05700 MOVEM SCP ;BYTE SIZE.
05800 ;; 5/74 SETZM DLK+3 ;TO READ FILES OFF DSK
05900 TRZE FL,RESTART
06000 JRST SETIN
06100 ;**** NEXT 2 ARE FOR SAVER
06200 MOVEI T,1
06300 MOVEM T,RECCT
06400 ;; 5/74 MOVE T1,[POINT 6,DLK]
06500 ;; SETZM DLK
06600 ;; SETZM DLK+1
06700 ;; MOVEI T2,12
06800 JRST SETIN
06900 ;***********↑↑↑↑↑
00100 RIN: ILDB TIB+1; GET FILE NAME
00200 CAIN 15
00300 JRST SETIN
00400 CAIN "."; AN EXTENSION
00500 JRST SETEX
00600 SUBI 40
00700 IDPB T1
00800 SOJG T2,RIN
00900 JRST SETIN
01000 TIB: 0
01100 POINT 7,0,35
01200 0
01300 TOB: 0
01400 POINT 7,0,35
01500 0
01600 TIBUF: 0
01700 XWD 21,.
01800 BLOCK 22
01900 TOBUF: 0
02000 XWD 21,.
02100 BLOCK 22
02200 ;THIS IS NOW IN FILBRK DLK: BLOCK 4
02300 IBUF: XWD 400000,BUF1+1; MAGIC TO KEEP SYSTEM
02400 SCP: POINT 7,0,35; HAPPY
02500 ICCNT: 0 ;BUFFER CHAR. COUNT.
02600 SETEX: TLZ T1,770000
02700 JRST RIN
02800 SETIN: MOVE 0,DLK+3 ;TO SAVE P,PN
02900 LOOKUP DT,DLK; GET FILE SETUP
03000 JRST NER; NON-EX FILE
03100 MOVEM 0,DLK+3 ;PUTS BACK P,PN
03200 PUSHJ P,RDBUF ;GET FIRST BUFFER
03300 MOVE BUF1+3 ;LINE NO. FIRST ?
03400 TRNE 1
03500 AOS SCP ;YES; ADVANCE SCP PAST IT.
03600 SETZM SNCHR
03700 SETZM FOONLY# ;BARF !!
03800 POPJ P,; DONE
03900 BUF1: 0
04000 XWD 201,BUF2+1
04100 BLOCK 202
04200 BUF2: 0
04300 XWD 201,BUF3+1
04400 BLOCK 202
04500 BUF3: 0
04600 XWD 201,BUF1+1
04700 BLOCK 202
04800
00100 AER1: MOVEI DEV1MS; ERROR ROUTINE FOR NOT AVAILABLE
00200 JSR TXTOUT; DECTAPE
00300 MOVEI T1,4
00400 MOVEI DNAM
00500 PUSHJ P,SIXOUT
00600 MOVEI DEV2MS
00700 JSR TXTOUT
00800 JRST SETUP
00900 NER: MOVEI NAM1MS
01000 JSR TXTOUT
01100 MOVEI T1,6
01200 MOVEI DLK
01300 PUSHJ P,SIXOUT
01400 HLRZ DLK+1
01500 JUMPE NEX1
01600 MOVEI "."
01700 IDPB TOB+1
01800 MOVEI T1,3
01900 MOVEI DLK+1
02000 PUSHJ P,SIXOUT
02100 NEX1: MOVEI NAM2MS
02200 JSR TXTOUT
02300 JRST SETUP
02400 NAM1MS: ASCIZ /
02500 FILE /
02600 NAM2MS: ASCIZ / NOT FOUND
02700 /
02800
02900 DECPNT: PUSHJ P,DECPNN ;SPACE COMES AFTER NUM IS TYPED.
03000 MOVEI A,40
03100 SOSGE TOB+2
03200 OUTPUT TTY,0
03300 IDPB A,TOB+1
03400 POPJ P,
03500
03600
03700 DECPNN: IDIVI A,12 ;PRINT DECIMAL INTEGER FROM A.
03800 HRLM B,(P) ;SAVE LOW ORDER DIGIT.
03900 SKIPE A ;DONE ?
04000 PUSHJ P,DECPNN ;NO. RECUR FOR REST OF DIGITS.
04100 HLRZ A,(P) ;YES. GET HIGH ORDER DIGIT.
04200 ADDI A,"0" ;CONVERT TO ASCII.
04300 SOSGE TOB+2 ;OUTPUT IT.
04400 OUTPUT TTY,0
04500 IDPB A,TOB+1
04600 POPJ P, ;RETURN.
00100 SIXOUT: TLO 440600 ; MAKE BYTE POINTER
00200 LOOPTS: SOJL T1,[POPJ P,]
00300 ILDB T,0
00400 JUMPE T,[POPJ P,]
00500 ADDI T,40
00600 IDPB T,TOB+1
00700 JRST LOOPTS
00800 TXTOUT: 0
00900 TLO 440700; ANOTHER POINTER
01000 LPT1: ILDB T,0
01100 JUMPE T,RETPT
01200 SOSGE TOB+2
01300 OUTPUT TTY,0
01400 IDPB T,TOB+1
01500 JRST LPT1
01600 RETPT: OUTPUT TTY,0
01700 JRST @TXTOUT
01800 DEV1MS: ASCIZ /
01900 DEVICE /
02000 DEV2MS: ASCIZ / NOT AVAILABLE
02100 /
02200 IMS: ASCIZ /
02300 * INPUT ? /
02400
02500 RDBUF: MOVEI [BYTE (7)15,12,52] ;ASCIZ / CR LF */
02600 MOVSI A,'TTY'
02700 CAME A,DNAM ;IS INPUT DEVICE A TTY ?
02800 TLO FL,NOSTAR ;NO. SUPRESS THE *.
02900 TLZN FL,NOSTAR ;PRINT IF NOSTAR NOT ON.
03000 CALLI 3 ;YES. TYPE CR LF *.
03100 ;; NEXT 2 FOR SAVER
03200 USETI DT,@RECCT# ;POSITION INPUT FILE TO RIGHT RECORD.
03300 AOS RECCT ;ADD 1 TO RECORD CTR
03400 INPUT DT,0 ;READ NEW INPUT BUFFER.
03500 STATZ DT,20000 ;END OF FILE SEEN ?
03600 JRST SETUP ;YES.
03700 MOVEI 4 ;MAKE SURE 0 WORD TERMINATES IT.
03800 ADD ICCNT ;CHAR. COUNT +4/5 IS WORD COUNT.
03900 MOVEI A,5 ;BECAUSE WE DON'T WANT TO LOSE B.
04000 IDIVM A ;SEE? NO RANDOM REMAINDER !!
04100 ADD A,SCP ;ADD BASE ADDRESS.
04200 IBP A ;BAGBITING SYSTEM.
04300 SETZM (A) ;ZERO IT.
04400 MOVE SCP
04500 MOVEM ISCP# ;SAVE FOR ERROR PRINTOUT.
04600 POPJ P,
00100 SUBTTL ALGOL SCANNER -- 9/8/66 D. POOLE
00200
00300 ;CALL IS PUSHJ P,-----. SCANS NEXT ATOMIC ELEMENT OF
00400 ; INPUT STRING, RETURNS ELEMENT IN ACCUM. 'A' AS FOLLOWS:
00500 ; UNDEFINED IDENTIFIER-- RETURNS 0.
00600 ; DECLARED IDENTIFIER--- 'A' CONTAINS RANDOM GOOD BITS FROM
00700 ; THE SYM. TBL. IN LEFT HALF, PTR. TO RGB WORD IN RT. HALF.
00800 ;RESERVED WORD OR SINGLE-CHARACTER OPERATOR--- 'A' CONTAINS
00900 ; THE RANDOM BITS WORD FROM EITHER THE RESERVED WORD TABLE
01000 ; OR THE CHAR. CONVERT TABLE, RESPECTIVELY.
01100
01200
01300 BUCKNO←←1; SEE DFUNC BEFORE CHANGING !!!!
01400
01500 ACCUM: BLOCK 40 ;GOOD ENOUGH FOR NOW...
01600
01700 SCANNS: TLOA FL,NOSTAR ;SUPRESS PRINTING OF *.
01800
01900 SCANR: TLOA FL,400000 ;ENTRY WHEN EXPECTING OPERATOR OR
02000 ; RESERVED WORD.
02100 SCANV: TLZ FL,400000 ;ENTRY WHEN EXPECTING VARIABLE.
02200
02300 SCAN:
02400 SKIPE A,SNCHR# ;IF SNCHR IS NON-ZERO,
02500 JRST SL1 ; IT IS THE NEXT CHAR. TO SCAN.
02600 SL10: ILDB A,SCP ;GET NEXT CHAR.
02700 SKIPN A,CTBL(A) ;SKIP LEADING BLANKS.
02800 JRST SL10
02900
03000 JUMPL A,SL1A ;IF OPERATOR, WE'RE DONE.
03100 TLNE A,SNUMF ;CHECK FOR PART OF A NUMBER.
03200 JRST SNUM1
03300 MOVE T2,[POINT 6,ACCUM,5] ;PREPARE TO SCAN AN
03400 SETZB T,ACCUM ;IDENTIFIER.
03500 MOVEM T,ACCUM+1
03600 MOVEM A,FOONLY
03700 SL2: IDPB A,T2 ;APPEND CHAR. TO IDENTIFIER.
03800 ILDB A,SCP ;NEXT CHAR.
03900 SKIPLE A,CTBL(A) ;CHECK FOR TERMINATOR.
04000 AOJA T,SL2 ;INCREMENT COUNT AND LOOP.
04100 TLNE A,SSPC2F ;DOES TERMINATING CHAR. REQUIRE
04200 JRST SSPCB ;IMMEDIATE ATTENTION ?
04300 MOVEM A,SNCHR ;NO, SAVE IT FOR NEXT TIME.
04400 ADDI T,1
04500 DPB T,[POINT 6,ACCUM,5] ;PUT COUNT IN FIRST CHAR.
04600 HRRZS T2
04700 SUBI T2,ACCUM
04800 HRRZM T2,ACCWC#
00100 MOVE A,ACCUM ;PREPARE TO SEARCH TABLES.
00200 MOVE C,ACCUM+1
00300 TLZE FL,400000 ;DO WE EXPECT AN OPERATOR ?
00400 JRST SRSCH ;YES; SEARCH RES. WD. TBL. FIRST
00500 SMSCH: MOVE T,A ;SEARCH MAIN SYM. TBL.
00600 IDIVI T,BUCKNO ;DO HASH ON IDENT.
00700 MOVMS T1 ;MAKE SURE IT'S POSITIVE.
00800 MOVEM T1,CBNO# ;SAVE BUCKET NO.
00900 HRRZ B,BUCTBL(T1) ;HEAD OF RIGHT BUCKET
01000 ; IN SYM. TBL.
01100 SL5: CAMN A,1(B) ;COMPARE FIRST WORDS.
01200 JRST SL4
01300 SL6: HRRZ B,(B) ;GET NEXT ELEMENT OF
01400 JRST SL5 ; THE LINKED LIST.
01500 SL4: CAIN B,A-1 ;FIRST WORD WAS EQUAL...
01600 JRST SNO ; WE ARE AT END OF BUCKET.
01700 SKIPN T1,T2
01800 JRST SFOUND ;ONLY 1 WORD; WE'RE DONE.
01900 CAME C,3(B) ;COMPARE SECOND WORDS...
02000 JRST SL6 ;NOPE.
02100 SOJE T1,SFOUND ;ANY MORE WORDS ?
02200 MOVE T3,[XWD B,4]; YES. PREPARE TO CHECK THEM.
02300 SL7: MOVE D,ACCUM-2(T3)
02400 CAME D,@T3
02500 JRST SL6 ;NOT EQUAL.
02600 SOJE T1,SFOUND ;MORE STILL ?
02700 AOJA T3,SL7 ;YES; KEEP CHECKING.
02800
02900 SFOUND: MOVEI A,2(B) ;FOUND HIM; CALC. PTR. TO RGB WORD.
03000 HLL A,(A) ;GET RANDOM GOOD BITS.
03100 HRRZ B,A
03200 SEXIT: CAIG T2,1 ;MORE THAN 2 WORDS OF NAME ?
03300 POPJ P, ;NO.
03400 SETZM ACCUM(T2) ;YES; ZERO OUT ALL THE WORDS OF
03500 SOJA T2,SEXIT ; ACCUM THAT WE USED.
03600
03700 SNO: TLCN FL,400000 ;NOT IN MAIN TBL; HAVE WE ALREADY
03800 JRST SRSCH ; SEARCHED RES. WORD TBL ?
03900 SN1: MOVE A,FOONLY ;GARPBAZ !
04000 TLNE A,FOOBIT
04100 JRST FOOSCH
04200 SCH1: SETZB A,B ;YES. RETURN 'UNDEFINED'.
04300 POPJ P,
04400
04500 SL1: SETZM SNCHR ;RETURN FOR A SPECIAL CHAR.
04600 SL1A: TLNN A,SSPCF+SSPC2F ;DOES IT NEED SPECIAL SERVICE ?
04700 POPJ P, ;NO.
04800 PUSHJ P,(A) ;YES. DISPATCH ON IT.
04900 JRST SL10 ;CONTINUE SCANNING.
00100 FOOSCH: LDB B,[POINT 6,ACCUM,17]
00200 TRNE FL,SFOOBT ;ARE WE DEFINING A FUNCTION ?
00300 JRST SCH1 ;YES. NO FOO-SYMBOLS ALLOWED.
00400 CAIG B,31 ;IS IT A DIGIT?
00500 CAIGE B,20
00600 JRST SCH1 ;NO.
00700 SUBI B,20 ; TO VALUE.
00800 LDB C,[POINT 6,ACCUM,23]
00900 JUMPE C,FSCH1
01000 LDB D,[POINT 6,ACCUM,29]
01100 JUMPN D,SCH1
01200 IMULI B,12 ;MUL. TENS DIGIT BY 10.
01300 CAIG C,31
01400 CAIGE C,20
01500 JRST SCH1
01600 ADDI B,-20(C) ;ADD IN ONE'S DIGIT.
01700 FSCH1: DPB B,[POINT 17,A,35] ;PUT NUMBER IN A.
01800 POPJ P, ;RETURN FROM SCAN.
01900
02000
02100 S.VT: ;HERE ON VERTICAL TAB.
02200 S.FF: ;FORM FEED.
02300 S.LF: ;LINE FEED
02400 SENDL: TLZ FL,ERRFLG ;END OF LINE. CLEAR ERROR FLAG.
02500 MOVEI A,1
02600 ADD A,SCP ;GET PTR TO NEXT WORD.
02700 SKIPN T,(A)
02800 JRST S.EOB ;ZERO WORD MEANS END OF BUFFER.
02900 TRNN T,1 ;IS IT A LINE NO. ?
03000 POPJ P, ;NO; CONTINUE SCANNING.
03100 TLZ A,770000 ;YES; ADVANCE PTR. PAST IT.
03200 MOVEM A,SCP
03300 POPJ P,
03400 S.EOB: PUSHJ P,RDBUF ;REFILL BUFFER.
03500 JRST SENDL
03600
03700 SSPCB: HALT
03800
03900 SSPCC: HALT
04000
04100 S.LT: ILDB A,SCP ;'<' SEEN; SKIP TO END OF LINE.
04200 CAIE A,12 ;A LINE FEED ?
04300 JRST S.LT ;NO.
04400 JRST SENDL
00100 SNUM1: MOVEI C,0 ;NUMBER SCANNER.
00200 CAMN A,DOTV ;FIRST THING A DECIMAL PT.?
00300 JRST SNUM6 ;YES
00400 MOVNI T,100 ;NO DEC PT. YET.
00500 SNUM2: IMULI C,12
00600 ADDI C,-20(A) ;CONVERT NEW DIGIT TO VALUE AND ADD IN
00700 AOSA T ;INCREMENT DEC. PLACE COUNT.
00800 SNUM6: MOVEI T,0 ;START COUNTING DEC. PLACES.
00900 ILDB A,SCP ;NEXT CHAR.
01000 SKIPG A,CTBL(A) ;GET MAGIC BITS.
01100 JRST SNUM7 ;IT'S A DELIMITER.
01200 TLNE A,SDFLG ;IS IT A DIGIT ?
01300 JRST SNUM2 ;YES.
01400 CAMN A,DOTV ;A DEC. PT. ?
01500 JRST SNUM6 ;YES.
01600 JRST SNUMX1
01700 SNUM7: TLNE A,SSPC2F ;DOES DELIM. REQUIRE INSTANT SERVICE ?
01800 JRST SSPCC ;YES.
01900 MOVEM A,SNCHR ;SAVE FOR NEXT TIME.
02000 SFLTIT: IDIVI C,400000 ;FLOAT IT.
02100 SKIPE C
02200 TLC C,254000
02300 TLC D,233000
02400 FAD C,D
02500 SKIPLE T
02600 FDVR C,[10.0] ;DIVIDE BY 10 ENOUGH TO GET
02700 SOJG T,.-1 ;DEC. PT. IN RIGHT PLACE.
02800 SKIPA T,[XWD FLTFLG,0] ;GET FLOATING PT. FLAG.
02900 SNFX: MOVSI T,FIXFLG
03000 HLLZ A,T ;COPY FLAG TO A.
03100 TRNN FL,SFOOBT
03200 TLZE FL,SNUMF1
03300 POPJ P,
00100 ;; NOW SEARCH NUMBER TABLE FOR THE NUMBER.
00200
00300 TDOA A,NUMBUC ;NUMBUC TO RT. HALF.
00400 SNUM4: HRR A,-1(A) ;GET NEXT LINK.
00500 CAME C,(A) ;IS IT EQUAL ?
00600 JRST .-2 ;NO.
00700 TRNN A,777760 ;ARE WE AT END OF TABLE ?
00800 JRST SNUMNO ;YES.
00900 TDNN T,-1(A) ;NO. DO TYPES MATCH ?
01000 JRST SNUM4 ;NO.
01100 POPJ P, ;YUP. WE'VE FOUND IT.
01200
01300 SNUMNO: TRNE FL,CSBRBT ;ARE WE INSIDE A FUNCTION DEFINITION ?
01400 JRST SNUMX ;YES.
01500 AOS B,JOBFF ;INSERT NEW NUMBER IN TABLE.
01600 HRR A,B
01700 EXCH B,NUMBUC ;UPDATE NUMBUC.
01800 HRRM B,-1(A) ;PUT IN NEW LINK.
01900 HLLM A,-1(A) ;PUT IN TYPE FLAG.
02000 MOVEM C,(A) ;ALSO VALUE.
02100 AOS T,JOBFF ;BUMP POINTER PAST VALUE.
02200 HRLM T,JOBSA
02300 POPJ P,
02400
02500 SNUMX: IOR T,VLOC ;WE WILL PUT NO. IN VARIABLES AREA.
02600 PUSH P,T ;SAVE PTR. TO LOC.
02700 MOVE A,C ;VALUE OF NO. TO A.
02800 MOVEI B,0 ;NO RELOCATION.
02900 PUSHJ P,EMVCDI ;EMIT TO VARIABLES BUFFER.
03000 JRST POPAJ ;SEE EMINST.
00100 ; RESERVED WORD TABLE SEARCHER.
00200
00300
00400 SRSCH: LDB B,[POINT 6,ACCUM,5] ;GET CHAR. COUNT.
00500 CAIL B,3 ;NO 1-CHAR. RES. WDS.
00600 CAILE B,13 ;ALSO NONE OF > 9 CHARS.
00700 JRST SRNO
00800 MOVE B,SRTBL1-2(B) ;GET RIGHT SECTION OF TBL.
00900 CAME A,(B) ;COMPARE FIRST WORD.
01000 SRS1: AOBJN B,.-1
01100 JUMPGE B,SRNO ;ARE WE AT END OF SETCTION ?
01200 CAME C,LRTBL(B) ;NO; COMPARE SECOND WORD.
01300 JRST SRS1
01400 MOVE A,2*LRTBL(B) ;THIS IS IT; GET GOOD BITS.
01500 TLNE A,SSPCF ;DOES IT NEED OUR ATTENTION ?
01600 JRST (A) ;YES.
01700 JRST SEXIT ;NO.
01800
01900 SRNO: TLCN FL,400000 ;NOT A RES. WORD; HAVE WE ALREADY
02000 JRST SMSCH ;SEARCHED MAIN SYM. TBL. ?
02100 JRST SN1 ; YES; RETURN.
02200
02300 .COMME: MOVE A,SNCHR ;A COMMENT; SKIP TO NEXT ';'
02400 SETZM SNCHR
02500 .COMM1: CAMN A,SEMICV
02600 JRST SCAN
02700 TLNE A,SSPCF+SSPC2F ;SPECIAL TREATMENT ?
02800 PUSHJ P,(A) ;YES.
02900 ILDB A,SCP
03000 MOVE A,CTBL(A)
03100 JRST .COMM1
03200
03300
03400 BUCTBL: REPEAT BUCKNO,<EXP TEMPSY> ;TABLE OF HEADS OF THE
03500 ;HASH-CODED BUCKETS IN SYM. TABLE.
03600
03700 NUMBUC: EXP C ;HEAD OF NUMBER TABLE
00100 ;THE CHARACTER CONVERSION TABLE -- GOOD BITS FOR EVERYONE !
00200 ; GET YOURS WHILE THEY LAST !
00300
00400 OPDEF ILG [XWD DF+SSPCF,SILCH]
00500
00600 CTBL: XWD DF+SSPCF,SENDL
00700 REPEAT 10,<ILG>
00800 0 ; HORIZONTAL TAB.
00900 XWD DF+SSPCF,S.LF ;LINE FEED
01000 XWD DF+SSPCF,S.VT ; VERTICAL TAB
01100 XWD DF+SSPCF,S.FF ;FORM FEED
01200 0 ;CARRIAGE RETURN.
01300 REPEAT 14,<ILG>
01400 XWD DF+SSPCF,SENDL ;↑Z.
01500 REPEAT 5,<ILG>
01600 0 ;SPACE
01700 REPEAT 7,<ILG>
01800 LPARV: XWD DF,1
01900 RPARV: XWD DF,2
02000 XWD DF+MULBIT,MULOP ; *
02100 PLSV: XWD DF+ADDBIT,ADDOP ; +
02200 COMMAV: XWD DF,COMMOP ; ,
02300 MINV: XWD DF+ADDBIT,SUBOP ; -
02400 DOTV: XWD SNUMF,"." ; .
02500 XWD DF+MULBIT,DIVOP ; /
02600 CTNUM: REPEAT 12,<XWD SDFLG+SNUMF,20+.-CTNUM> ; THE DIGITS.
02700
02800 COLONV: XWD DF,3 ; :
02900 SEMICV: XWD DF,4 ; ;
03000 XWD DF+SSPCF,S.LT ;<
03100 ;; XWD DF+RELBIT,EOP ; =
03200 XWD DF,ASNOP ;← AND = DO THE SAME THING. 5/74
03300 XWD DF+RELBIT,GOP ; >
03400 REPEAT 2,<ILG>
03500 CTLTR: REPEAT =5,<XWD 0,41+.-CTLTR> ;THE LETTERS.
03600 41+.-CTLTR ;F
03700 REPEAT =9,<41+.-CTLTR>
03800 XWD FOOBIT,41+.-CTLTR+400000 ;P
03900 REPEAT 4,<41+.-CTLTR>
04000 XWD FOOBIT,41+.-CTLTR
04100 REPEAT 5,<41+.-CTLTR>
04200
04300 LFTBRK: XWD DF,5 ; [
04400 ILG
04500 RGTBRK: XWD DF,6
04600 UARV: XWD DF,EXPOP ; ↑
04700 LARV: XWD DF,ASNOP ;← LEFT ARROW??
04800 REPEAT 35,<ILG>
04900 ALTV: XWD DF,. ;ALT MODE.
05000 REPEAT 2,<ILG>
05100 ; END OF CONVERT TABLE.
00100 DEFINE PUT1 (N,Y)
00200 < FOR X IN (Y)
00300 <Q←<SIXBIT /X/>
00400 N*10000000000+(7777777777&(Q/100))
00500 >>
00600
00700 DEFINE PUT2 (Y)
00800 <FOR X IN (Y)
00900 <SIXBIT /X/
01000 >>
01100
01200 RTBL: ;THE RESERVED WORD TABLE.
01300 RT3C: PUT1 (3,END) ;THE 3-LETTER SECTION.
01400 RT4C: PUT1(4,<PLAY>)
01500 RT5C: PUT1(5,<ARRAY>)
01600 RT6C: PUT1 (6,FINIS) ;THE 6-LETTER SECTION.
01700 RT7C: PUT1 (7,<COMME,COMPI>)
01800 RT8C: PUT1 (10,<VARIA,FUNCT,EXTER>) ;VARIABLE
01900 RT10C: PUT1 (12,INSTR) ;
02000
02100 LRTBL←←.-RTBL
02200
02300 RTBL2: 0 ;END
02400 0 ;PLAY.
02500 0
02600 PUT2 (H)
02700 PUT2 (<NT,LE>) ;COMMENT
02800 PUT2 (<BLE,ION,NAL>)
02900 PUT2 (UMENT) ;INSTRUMENT
03000
03100 RF←←DF+RFLG
03200
03300 RTBL3:
03400 ENDV: XWD RF,.
03500 PLAYV: XWD RF,.
03600 ARRV: XWD RF+DECLBIT,DARR
03700 FINV: XWD RF,.
03800 COMV: XWD SSPCF,.COMME
03900 COMPV: XWD RF,.
04000 VARV: XWD RF+DECLBIT,DVRBL
04100 FUNV: XWD RF+DECLBIT,DFUNC ;FUNCTION
04200 EXTV: XWD RF+DECLBIT,EXTD
04300 INSV: XWD RF+DECLBIT,CINS
04400
04500 SRTBL1: 0 ;2
04600 XWD -1,RT3C
04700 XWD -1,RT4C
04800 XWD -1,RT5C
04900 XWD -1,RT6C
05000 XWD -2,RT7C
05100 XWD -3,RT8C
05200 0
05300 XWD -1,RT10C
05400 0
05500 SRSFOO: JUMP 2*LRTBL(B)
00100 ;; MORE BITS AND PARAMETERS.
00200 RELBIT←←0
00300
00400 ;SIZES OF VARIOUS STACKS AND TABLES:
00500 LOBUFS←←200
00600 LUOTBL←←62
00700 LPLIST←←100
00800 LOSTK←←40
00900 LPA←←62
01000 LRQ←←=75 ;LENGTH OF RUN QUEUE.
01100
01200 ;SPECIAL AC DEFINITIONS :
01300 RA←16 ;AC FOR JSA LINKAGE AT RUNTIME.
01400
01500
01600 DEFINE MAKOP1 (X)
01700 <FOR @$ A IN (X)
01800 <A$OP: HALT
01900 >>
02000
02100 MAKOP1 <PW,COMM,L,E,G,EXP,ENDS,WHLS>
02200
02300 ;; TEMPORARY AND DEBUGGING ROUTINES:
02400
02500 GO: MOVE P,[IOWD LPLIST,PLIST]
02600 AOSE ONCEFG ;IS THIS FIRST TIME THROUGH ?
02700 JRST GOA ;NO. LEAVE JOBFF AT CURRENT PLACE.
02800 HRLZ 116 ;YES. GET BOTTOM OF SYM. TAB. FROM JOBSYM.
02900 SUB 116 ;ADD LENGTH OF SYM. TAB.
03000 HRLM JOBFF
03100 GOA: HRR JOBFF
03200 HRLM JOBSA
03300 MOVEI FL,0
03400 PUSHJ P,SETUP
03500 GOB: MOVE P,[IOWD LPLIST,PLIST]
03600 MOVE [JSR ERR1] ;SET UP FOR ERROR UUO.
03700 MOVEM 41
03800 MOVE JOBREL
03900 MOVEM JOBSYM
04000 JRST SCHOWN
04100
04200 ONCEFG: -1
04300
04400 DEFINE ERROR (M)
04500 <XWD 1000,[ASCIZ /M/] >
04600
04700
04800 UDIERR: ERROR (UNDEFINED IDENTIFIER)
04900
05000 SILCH: ERROR (ILLEGAL CHARACTER)
05100 SNUMX1: ERROR(ILLEGAL CHAR. IN NUMBER)
05200 FNDWV: HALT
05300 ;USEFUL F4 FUNCTIONS TO HAVE AROUND....
05400 EXTERNAL SIN,COS,EXP,ALOG,SQRT
05500
00100 TEMPSY: EXP TMPS1Z
00200 PUT1 5,OSCIL
00300 XWD UGBIT,.+2
00400 0
00500 JSP RA,@OSCIL ;POINTER DID NOT RESET WITH '1,5,0,1' IN NEXT!!!!
00600 BYTE (6)4,2,2,1,4,0,1;***** JULY 3,71 THIS ENDED '1,5,0,1' ****
00700 TMPS1Z: TMPS1
00800 PUT1 6,ZOSCI
00900 XWD UGBIT,.+3
01000 PUT2 (L)
01100 0
01200 JSP RA,@ZOSCIL
01300 BYTE (6)4,2,2,1,5,0,1
01400 ;CHANGE LAST OF ABOVE TO .. 4,0,1 TO MAKE ZOSCIL NOT LIKE COSCIL
01500 TMPS1: EXP TIMESC+1
01600 PUT1 6,TIMES
01700 XWD VRBLBT,TIMESC
01800 PUT2 C
01900 TIMESC: 1.0
02000 EXP SRATE+1
02100 PUT1 5,SRATE
02200 XWD VRBLBT,SRATE
02300 SRATE: 10000.0
02400 EXP NCHNS+1
02500 PUT1 5,NCHNS
02600 XWD VRBLBT,NCHNS
02700 NCHNS: 1
02800 EXP LSBUF+1
02900 PUT1 5,LSBUF
03000 XWD VRBLBT,LSBUF
03100 LSBUF: 1000
03200 EXP TMPS2
03300 PUT1 3,OUT
03400 XWD UGBIT,.+2
03500 0
03600 JSA RA,@OUT
03700 BYTE (6)1,2,0,0
03800 TMPS2: EXP TMPS3
03900 PUT1 4,OUT2
04000 XWD UGBIT,.+2
04100 0
04200 JSA RA,@OUT2
04300 BYTE (6)3,2,2,2,0,0
04400 TMPS3: TMPS3A
04500 PUT1 5,SPEED
04600 XWD VRBLBT,SPEED
04700 SPEED: 1
04800 TMPS3A: TMPS11
04900 PUT1 6,ZINTR
05000 XWD UGBIT,.+3
05100 PUT2 P
05200 JSA RA,IINTRP
05300 JSP RA,@ZINTRP
05400 BYTE (6)5,2,2,5,1,4,0,T
05500
05600 TMPS11: TMNOSA
05700 PUT1 6,VFMUL
05800 XWD UGBIT,.+3
05900 PUT2 T
06000 0
06100 JSP RA,@VFMULT
06200 BYTE (6)3,2,2,1,0,T
06300 ; OSCIL IS NOW THE NOSCIL...JMG 7/14/73
06400
06500 ; SOMEDAY, IF IT IS EVER USED, SOMEONE COULD CHANGE
06600 ; THE NAME OF NOSCA TO OSCA, ETC.
06700 ;TMPS12: TMNOSA
06800 ; PUT1 6,NOSCI
06900 ; XWD UGBIT,.+3
07000 ; PUT2 L
07100 ; 0
07200 ; JSP RA,@NOSCIL
07300 ; BYTE (6)4,2,2,1,4,0,1
07400
07500 TMNOSA: TMPS13
07600 PUT1 5,NOSCA
07700 XWD UGBIT,.+2
07800 JSA RA,INOSCA
07900 JSP RA,@NOSCA
08000 BYTE (6)5,2,2,2,1,5,0,T
08100
08200 ;TMPS13: TMPS14
08300 ; PUT1 10,DISKF
08400 ; XWD VRBLBT,DISKFL
08500 ; PUT2 LAG
08600 ;DISKFL: 0
08700
08800 TMPS13: TMPS24
08900 PUT1 5,INTRP
09000 XWD UGBIT,.+2
09100 JSA RA,IINTRP
09200 JSP RA,@INTRP
09300 BYTE (6)5,2,2,5,1,4,0,T
09400 TMPS24: TMPS14
09500 PUT1 4,READ
09600 XWD UGBIT,.+2
09700 JSP RA,READI
09800 JSP RA,@READ
09900 BYTE (6)6,2,2,1,2,5,5,0,T
10000 TMPS14: TMPS15
10100 PUT1 4,REVX
10200 XWD UGBIT,.+2
10300 JSP RA,REVXI
10400 JSP RA,@REVX
10500 BYTE (6)20,2,2,2,2,2,2,2,2,2,4,4,4,4,4,1,4,0,T
10600
10700 TMPS15: .+3
10800 PUT1 4,OUTA
10900 XWD VRBLBT,OUTA
11000 .+3
11100 PUT1 4,OUTB
11200 XWD VRBLBT,OUTB
11300 .+3
11400 PUT1 4,OUTC
11500 XWD VRBLBT,OUTC
11600 .+4 ;DOPLAY←1=WILL PLAY WHEN WRITING SMPLS ON DSK
11700 PUT1 6,DOPLA
11800 XWD VRBLBT,DOPLAY#
11900 PUT2 Y
12000 .+3
12100 PUT1 4,OUTD
12200 XWD VRBLBT,OUTD
12300 .+4 ;RCDFLG←1 PUTS SAMPLES ON DSK UNDER 'MUSAA','MUSAB',ETC.
12350 PUT1 6,RCDFL
12400 XWD VRBLBT,RCDFLG#
12600 PUT2 G
13100 .+4
13200 PUT1 6,BIGBI
13300 XWD VRBLBT,BIGBIT#
13400 PUT2 T
13500 .+6
13600 PUT1 5,VALUE
13700 XWD UGBIT,.+2
13800 0
13900 JSP RA,@VALUE
14000 BYTE (6)1,2,0,T
14100 .+5
14200 PUT1 4,RAND
14300 XWD FUNBIT,.+1
14400 PUSHJ P,RAND
14500 BYTE (6)0,T
14600 FRSTB+1
14700 PUT1 =9,FIRST
14800 XWD VRBLBT,FRSTB
14900 PUT2 BAND
15000 FRSTB: 0
15100 .+5
15200 PUT1 5,PRINT
15300 XWD FUNBIT,.+1
15400 JSA RA,FOOPRT
15500 BYTE (6)1,2,0,0
15600 .+3
15700 PUT1 3,RDA
15800 XWD RVBT∨VRBLBT,RDA
15900 .+3
16000 PUT1 3,RDB
16100 XWD RVBT∨VRBLBT,RDB
16200 .+3
16300 PUT1 3,RDC
16400 XWD RVBT∨VRBLBT,RDC
16500 .+3
16600 PUT1 3,RDD
16700 XWD RVBT∨VRBLBT,RDD
00100 TMPSA: EXP TMPS4 ;LINEN.
00200 PUT1 5,LINEN
00300 XWD UGBIT,.+2
00400 JSA RA,LINEN1
00500 JSP RA,@LINEN
00600 ; BYTE (6)13,4,4,4,2,2,2,2,1,4,4,4,0,1
00700 BYTE (6)13,4,4,4,2,2,2,2,1,2,4,4,0,1
00800 ;NOW YOU MUST RESET PTR IN LINEN
00900 TMPS4: EXP TMPS4A
01000 ;TMPS4: EXP TMPS5
01100 PUT1 5,EXPEN
01200 XWD UGBIT,.+2
01300 0
01400 JSP RA,@EXPEN
01500 BYTE (6)4,2,2,1,4,0,1
01600
01700 TMPS4A: EXP TMPS5
01800 PUT1 6,ZEXPE
01900 XWD UGBIT,.+3
02000 PUT2 N
02100 0
02200 JSP RA,@ZEXPEN
02300 BYTE (6)4,2,2,1,4,0,1
02400
02500 TMPS5: EXP TMPS6
02600 PUT1 (4,REV1) ;REV1
02700 XWD UGBIT,.+2
02800 JSP RA,REVI
02900 JSP RA,@REV1
03000 BYTE (6)6,2,2,2,1,5,4,0,1
03100 TMPS6: EXP TMPS7
03200 PUT1 4,REV2
03300 XWD UGBIT,.+2
03400 JSP RA,REVI
03500 JSP RA,@REV2
03600 BYTE (6)6,2,2,2,1,5,4,0,1
03700
03800 TMPS7: EXP TMPS8
03900 PUT1 (7,REVIN) ;REVINIT.
04000 XWD VRBLBT,REVINI
04100 PUT2 IT
04200 REVINI: 0
04300
04400 TMPS8: EXP TMPS9
04500 PUT1 (5,RANDH)
04600 XWD UGBIT,.+2
04700 JSP RA,IRANDH
04800 JSP RA,@RANDH
04900 BYTE (6)4,2,2,4,4,0,1
05000 TMPS9: EXP TMPS10
05100 PUT1 (5,RANDI)
05200 XWD UGBIT,.+2
05300 JSP RA,IRANDI
05400 JSP RA,@RANDI
05500 BYTE (6)5,2,2,4,4,4,0,1
05600 TMPS10: EXP A-1
05700 PUT1 6,COSCI
05800 XWD UGBIT,.+3
05900 PUT2 L
06000 0
06100 ; JSP RA,@NOSCIL
06200 JSP RA,@OSCIL
06300 BYTE (6)4,2,2,1,5,0,1
06400
00100 ;; HERE ARE SOME WONDERFUL UNIT GENERATORS.
00200
00300 ; THIS IS THE OLD OSCIL WHICH DOESN'T LIKE NEG. INCS.
00400 ;OSCIL: MOVE INSXR,3(RA)
00500 ; FIX INSXR,233000
00600 ; TRZE INSXR,777000
00700 ; JSP T1,OSCIL1
00800 ; MOVE T,@2(RA)
00900 ; FMPR T,@(RA)
01000 ; SKIPGE T1,@1(RA) ;OSCIL DOESN'T WANT NEG. INC.
01100 ; ERROR (NEGATIVE INC. TO OSCIL)
01200 ; FADM T1,3(RA)
01300 ; JRST 4(RA)
01400 NOSCA: ADDI RA,1
01500 ;NOSCIL: MOVE INSXR,3(RA)
01600 OSCIL: MOVE INSXR,3(RA)
01700 ;;*** CAUSE OF ROUNDOFF PROBS???? FAD INSXR,[0.5]
01800 ;; HRLZI T1,233000
01900 ;; UFA T1,INSXR
02000 ; THE ABOVE 2 INST'S REPLACE THE FIX FOR INDEXING
02100 FIX INSXR,233000
02200 TRZE INSXR,777000
02300 JSP T1,OSCIL1
02400 MOVE T,@2(RA)
02500 FMPR T,@(RA)
02600 MOVE T1,@1(RA)
02700 FADM T1,3(RA)
02800 JRST 4(RA)
02900 OSCIL1: MOVSI (-512.0) ;WRAP AROUND THE POINTER.
03000 JUMPGE INSXR,.+2
03100 MOVNS 0 ;IF NEG. INC., WRAP AROUND OTHER WAY.
03200 FADM 3(RA)
03300 HRLI INSXR,0 ;TO ALLOW ZOSCIL=NOSCIL
03400 JRST (T1)
03500
03600 OUT: 0
03700 MOVE @(RA) ;PICK UP INPUT.
03800 FADM OUTA ;ACCUMULATE INTO OUTPUT ARRAY.
03900 POPJ P, ;RETURN FROM INSTRUMENT.
04000
04100 OUT2: 0
04200 MOVE @(RA)
04300 MOVE 1,0
04400 FMP @1(RA)
04500 FADM OUTA ;
04600 FMP 1,@2(RA)
04700 FADM 1,OUTB
04800 POPJ P,
04900
05000 EXPEN: MOVE INSXR,@1(RA) ;GET INCREMENT.
05100 FADB INSXR,3(RA) ;INCREMENT POINTER.
05200 FIX INSXR,233000
05300 ;; HRLZI T1,233000
05400 ;; UFA T1,INSXR
05500 ; CAIL INSXR,777 ;IF GREATER THAN 512, STICK
05600 TRZE INSXR,777000
05700 EXPEN2: MOVEI INSXR,777 ;AT LAST ELEMENT OF ARRAY.
05800 MOVE T,@2(RA) ;GET ARRAY ELEMENT.
05900 FMPR T,@(RA) ;MULTIPLY BY AMPLITUDE.
06000 JRST 4(RA) ;RETURN.
06100 VFM2: FSBR INSXR,[512.0] ;YOU MUST NOW SET PTR FOR VFMULT!
06200 MOVEM INSXR,@VFMULT
06300
06400 VFMULT: MOVE INSXR,@1(RA) ;GET POINTER INPUT.
06500 CAML INSXR,[512.0]
06600 JRST VFM2
06700 FIX INSXR,233000
06800 ;; HRLZI T1,233000
06900 ;; UFA T1,INSXR
07000 MOVE T,@2(RA) ;GET INDICATED ELEMENT OF ARRAY.
07100 FMPR T,@(RA) ;MULT. BY AMPLITUDE.
07200 JRST 3(RA)
07300
07400 INOSCA: 0
07500 MOVE T,(RA)
07600 MOVE T1,@-6(T)
07700 MOVEM T1,-2(T)
07800 JRA RA,1(RA)
07900 INTRP: ADDI RA,1
08000 MOVE INSXR,3(RA)
08100 FIX INSXR,233000
08200 ;; HRLZI T1,233000
08300 ;; UFA T1,INSXR
08400 TRZE INSXR,777000
08500 JSP T1,OSCIL1
08600 MOVE T,@2(RA)
08700 FMPR T,@(RA)
08800 FADR T,@-1(RA)
08900 MOVE T1,1(RA)
09000 FADM T1,3(RA)
09100 JRST 4(RA)
09200
09300 IINTRP: 0
09400 MOVE T,(RA)
09500 MOVE T1,@-5(T)
09600 FSBR T1,@-6(T)
09700 MOVEM T1,@-5(T)
09800 MOVSI T1,(512.0)
09900 FDVR T1,SRATE
10000 FDVR T1,PBASE+2
10100 MOVEM T1,-4(T)
10200 JRA RA,1(RA)
10300
10400 ZEXPEN: SKIPGE INSXR,3(RA) ;ZEXPEN WORKS LIKE ZOSCIL AND EXPEN!
10500 JRST[ ERROR (NEGATIVE INC. TO ZEXPEN)
10600 JSP T1,OSCIL1 ;DO WRAPAROUND ANYWAY
10700 JRST .+1] ;LET THE LOSER CONTINUE
10800 ; IT TAKES THESE 4 INST'S TO DO A GOOD FIX FOR FURTHER USE
10900 FIX INSXR,233000
11000 ;; HRLZI T1,233000
11100 ;; UFA T1,INSXR
11200 ;; JUMPE INSXR,.+2
11300 ;; TLC INSXR,233000
11400 CAIL INSXR,777 ;IF GREATER THAN 511, STICK
11500 JRST EXPEN2 ;AT LAST ELEMENT (WE WON'T NEED TO INTERPOLATE)
11600 MOVE T,@2(RA) ;PICK UP FIRST ELEMENT
11700 move insxr ;SAVE INDEX
11800 move t1,t ;COPY FIRST ELEMENT
11900 addi insxr,1 ;NO, INCREMENT INDEX
12000 fsbr t1,@2(ra) ;GET DWFFERENCE IN VALUE I
12100 fsc 233 ;(FLOAT THE INDEX)
12200 fsb 3(ra) ;GET DIFFERENCE IN INDEX INTO 0
12300 fmpr t1,0 ;THE PRODUCT OF THE ABOVE TWO DIFFERENCES
12400 fadr t,t1 ;IS ADDED TO THE FIRST ELEMENT
12500 FMPR T,@(RA) ;SCALED BY AMPLITUDE
12600 MOVE T1,@1(RA) ;UPDATE SUM OF INCREMENTS
12700 FADM T1,3(RA)
12800 JRST 4(RA)
12900
13000 ZINTRP: ADDI RA,1 ;AN INTERPOLATING INTRP!
13100 MOVE INSXR,3(RA)
13200 FIX INSXR,233000
13300 ;; HRLZI T1,233000
13400 ;; UFA T1,INSXR
13500 ;; JUMPE INSXR,.+2
13600 ;; TLC INSXR,233000
13700 TRZE INSXR,777000 ;DID WE RUN OVER?
13800 JSP T1,OSCIL1 ;YES, DO WRAPAROUND (BUT IT REALLY SHOULDN'T!)
13900 MOVE T,@2(RA) ;PICK UP FIRST ELEMENT
14000 move insxr ;SAVE INDEX
14100 move t1,t ;COPY FIRST ELEMENT
14200 cain insxr,777 ;ARE WE AT THE LAST ELEMENT
14300 tdza insxr,insxr ;YES, SET INDEX TO ZERO AND SKIP
14400 addi insxr,1 ;NO, INCREMENT INDEX
14500 fsbr t1,@2(ra) ;GET DIFFERENCE IN VALUE I
14600 fsc 233 ;(FLOAT THE INDEX)
14700 fsb 3(ra) ;GET DIFFERENCE IN INDEX INTO 0
14800 fmpr t1,0 ;THE PRODUCT OF THE ABOVE TWO DIFFERENCES
14900 fadr t,t1 ;IS ADDED TO THE FIRST ELEMENT
15000 MOVE @(RA) ;GET SECOND VALUE
15100 FSBR @-1(RA) ;SUBTRACT THE FIRST
15200 FMPR T,0 ;MULIPLY BY DIFFENCE BETWEEN TWO VALUES
15300 FADR T,@-1(RA) ;AND ADD TO THE FIRST VALUE
15400 MOVE T1,1(RA) ;UPDATE SUM OF INCREMENTS
15500 FADM T1,3(RA)
15600 JRST 4(RA)
15700
15800 READ: AOS INSXR,4(RA)
15900 CAML INSXR,5(RA)
16000 JRST READ1
16100 MOVEI T,0
16200 LCS2: MOVE @2(RA)
16300 MOVEM RDA(T)
16400 ADDI T,1
16500 CAML T,3(RA)
16600 JRST 7(RA)
16700 AOS INSXR,4(RA)
16800 JRST LCS2
16900
17000 READ1: MOVE 2(RA)
17100 MOVEM LCS+3
17200 SUBI 1
17300 HRRZM LCS+4
17400 LCS: JSA 16,READIN
17500 0
17600 0
17700 0
17800 0
17900 [-1]
18000 SETZB INSXR,4(RA)
18100 JRST READ+3
18200
18300 READI: MOVE T,(RA)
18400 MOVE T2,@-4(T)
18500 FIX T2,233000
18600 ;******↑↑↑↑↑↑ OK FOR EXPORT ????? 5/74
18700 MOVEM T2,-4(T)
18800 MOVE T2,-7(T)
18900 MOVEM T2,LCS1+1
19000 MOVE T2,-6(T)
19100 MOVEM T2,LCS1+2
19200 MOVE T1,-5(T)
19300 MOVE T2, -1(T1)
19400 MOVEM T2,-2(T)
19500 SETOM -3(T)
19600 MOVEM T1,LCS1+3
19700 LCS1: JSA RA,READIN
19800 0
19900 0
20000 0
20100 T2
20200 [0]
20300 JRST 1(RA)
20400
20500 ZOSCIL: MOVE INSXR,3(RA) ;ZOSCIL WORKS LIKE COSCIL AND NOSCIL!
20600 FIX INSXR,233000
20700 ;; HRLZI T1,233000
20800 ;; UFA T1,INSXR
20900 ;; JUMPE INSXR,.+2
21000 ;; TLC INSXR,233000
21100 TRZE INSXR,777000
21200 JSP T1,OSCIL1
21300 MOVE T,@2(RA)
21400 move insxr
21500 move t1,t
21600 cain insxr,777
21700 tdza insxr,insxr
21800 addi insxr,1
21900 fsbr t1,@2(ra)
22000 fsc 233
22100 fsb 3(ra)
22200 fmpr t1,0
22300 fadr t,t1
22400 FMPR T,@(RA)
22500 MOVE T1,@1(RA)
22600 FADM T1,3(RA)
22700 JRST 4(RA)
22800
00100 ;; REVERBERATION UNIT GENERATORS.
00200 ; REV1 IS THE SIMPLE FED-BACK DELAY LOOP, OR 'COMB FILTER'.
00300
00400 REV1: AOS INSXR,4(RA) ;INCREMENT OUTPUT PTR.
00500 CAML INSXR,5(RA) ;IS IT TIME TO WRAP AROUND ?
00600 SETZB INSXR,4(RA) ;YES.
00700 MOVE 1,@3(RA) ;GET OUTPUT OF DELAY LINE.
00800 MOVE 2,1 ;LEAVE IN 1 AS FINAL OUTPUT.
00900 FMPR 2,@2(RA) ;MULTIPLY BY FEEDBACK GAIN.
01000 ;REVA: MOVE @1(RA) ;GET DELAY TIME, T.
01100 ; FIX 233000
01200 ; ADD INSXR,0 ;MOVE PTR. AROUND TO INPUT END.
01300 ; CAML INSXR,5(RA) ;PROBABLY HAVE TO WRAP AROUND..
01400 ; SUB INSXR,5(RA) ;YUP. SUBTRACT LENGTH OF DELAY ARRAY.
01500 ; THE ABOVE 5 INSTRUCTIONS ALLOW A DYNAMICALLY CONTROLLED
01600 ; DELAY TIME IN REVERB. TO INSTITUTE, CHANGE THE LOC. OF
01700 ; 'REVA:' BACK TO ABOVE AND DE-COMMENT. THE PRESENT REVERB
01800 ; ASSUMES THAT THE ARRAY LENGTH IS THE DELAY, SO THE ARGU-
01900 ; MENT IN THE UG IS IGNORED... JMG 7/14/73
02000 REVA: FADR 2,@(RA) ;ADD IN THE INPUT SAMPLE.
02100 JFCL 1,[SETZB 2,1 ;FLOAT. UNDER FLOW
02200 SETOM FXUFLG#
02300 JRST .+1] ;THESE WERE ON JC,MUS. WHY???
02400 MOVEM 2,@3(RA) ;PLACE IN INPUT OF DELAY LINE.
02500 JRST 6(RA) ;RETURN.
02600
02700 ;REV2 IS THE ALL-PASS REVERBERATOR.
02800
02900 REV2: AOS INSXR,4(RA) ;CALC. PTR. AS IN REV1.
03000 CAML INSXR,5(RA)
03100 SETZB INSXR,4(RA)
03200 ;; MOVN 1,@3(RA) ;GET NEGATIVE OF OUTPUT OF DELAY.
03300 ;; MOVN 0,@2(RA) ;ALSO NEGATIVE OF GAIN, G.
03400 ;; FMPR 1,0 ;FORM GAIN*OUTPUT
03500 ;; MOVE 2,1 ;(NOTE THIS IS POSITIVE).
03600 ;; FMPR 1,0 ;FORM -G↑2 * OUTPUT.
03700 ;; FADR 1,@3(RA) ;(1-G↑2) * OUTPUT.
03800 ;; FMPR 0,@(RA) ;FORM -G * INPUT.
03900 ;; FADR 1,0 ;FINAL OUTPUT IS -G*IN +(1-G↑2)*OUT.
04000 ;; JRST REVA ;FROM HERE ON, SAME AS REV1.
04100 MOVE 2,@2(RA) ;GET GAIN, G
04200 FMPR 2,@(RA) ;MULTIPLY BY INPUT
04300 FADR 2,@3(RA) ;ADD IN OUTPUT OF DELAY
04400 MOVN 1,2 ;TAKE -(OUTPUT+G+IN)
04500 FMPR 1,@2(RA) ;SCALE BY GAIN
04600 FADR 1,@(RA) ;ADD INPUT
04700 JFCL 1,[SETZB 2,1 ;FLOATING UNDERFLOW
04800 SETOM FXUFLG#
04900 JRST .+1]
05000 MOVEM 1,@3(RA) ;NEW DELAY INPUT
05100 JRST 6(RA) ;RETURN WITH ANSWER IN 2
05200 ; NEW REV. 1 LESS MULT. A.MOORER, 5/74
05300
05400 ; THIS IS THE I-TIME CODE FOR REV1 AND REV2.
05500
05600 REVI: HRRZ T1,(RA) ;GET PTR. TO END OF REV PARAMS.
05700 MOVNI INSXR,1 ;INSXR←-1
05800 HRRZ @-4(T1) ;GET -1ST ELEMENT OF ARRAY (THE LENGTH)
05900 MOVEM -2(T1) ;PLACE IN THE SECOND DUMMY PARAM.
06000 SKIPN REVINI ;SHOULD WE INIT. THE DELAY ARRAY ?
06100 JRST 1(RA) ;NO.
06200 SETZM -3(T1) ;YES. FIRST CLEAR THE POINTER LOC.
06300 HRRZ T,-4(T1) ;GET PTR. TO ARRAY.
06400 REVI2: ADDI -1(T) ; 0 NOW POINTS TO TOP OF ARRAY.
06500 HRL T,T
06600 SETZM (T) ;CLEAR FIRST ELEMENT OF ARRAY.
06700 ADDI T,1 ;FORM BLT POINTER.
06800 BLT T,@0 ;CLEAR REST OF ARRAY.
06900 JRST 1(RA)
07000
00100 ;; MORE GENERATORS.
00200
00300 LINEN: MOVE INSXR,11(RA) ;GET INCREMENT.
00400 ; FADB INSXR,10(RA) ;ADD TO POINTER.
00500 FADB INSXR,@10(RA) ;NOW YOU MUST RESET PTR
00600 LINEN4: CAML INSXR,12(RA) ;ARE WE PAST END OF SECTION ?
00700 JRST LINEN2 ;YES.
00800 FIX INSXR,233000
00900 MOVE T,@3(RA) ;AMPLITUDE.
01000 FMPR T,@7(RA) ;MULT. BY ARRAY ELEMENT.
01100 JRST 13(RA) ;RETURN.
01200
01300 LINEN2: MOVE T,12(RA) ;PICK UP CURRENT LIMIT.
01400 FIX T,242000
01500 CAIL T,3 ;END OF ARRAY ?
01600 JRST LINEN3 ;YES.
01700 HRLI T,RA ;PREPARE FOR INDEXING...
01800 MOVE @T ;PICK UP NEXT INCREMENT.
01900 MOVEM 11(RA) ;PUT AWAY.
02000 MOVSI (128.0)
02100 FADM 12(RA) ;INCREMENT LIMIT TO NEXT VALUE.
02200 JRST LINEN4
02300 LINEN3: MOVEI 14(RA) ;FAKE UP A PARAMETER FOR LINEN1.
02400 MOVEM .+2
02500 JSA RA,LINEN1 ;RE-INITIALIZE THE GENERATOR.
02600 0 ;
02700 ; SETZM 10(RA) ;RESET PTR.
02800 SETZM @10(RA) ;NOW YOU MUST RESET PTR
02900 SETZM 11(RA) ;AND INCREMENT.
03000 SETZM 12(RA) ;...AND LIMIT.
03100 JRST LINEN
03200
03300 LINEN1: 0 ;THE INITIALIZING CODE FOR LINEN.
03400 MOVE T2,(RA) ;GET POINTER TO END OF PARAMETERS.
03500 MOVE T1,TIMESC ;CALC. 128*(BEATS/SAMPLE)
03600 FDVR T1,SRATE
03700 FSC T1,7
03800 MOVE T,@-10(T2) ;GET RISE TIME IN BEATS.
03900 FDVRM T1,T ;INCREMENT←T1/TIME (=128/(TIME IN SAMPS))
04000 MOVEM T,-14(T2) ;PLACE IN PARAMETER 0.
04100 MOVE T,@-6(T2) ;DURATION OF NOTE IN BEATS...
04200 FSBR T,@-7(T2) ;...MINUS FALL TIME..
04300 FSBR T,@-10(T2) ;...MINUS RISE TIME.
04400 FDVRM T1,T ;CHANGE TO INCREMENT.
04500 MOVEM T,-13(T2) ;PLACE IN PARAMETER 1.
04600 FDVR T1,@-7(T2) ;INCREMENT FOR FALL TIME.
04700 MOVEM T1,-12(T2) ;PLACE IN PARAMETER 2.
04800 JRA RA,1(RA)
04900
05000 VALUE: MOVE T,@(RA) ;DUMMY UNIT GENERATOR... OUTPUT IS
05100 JRST 1(RA) ;SAME AS ITS PARAMETER.
00100 ;; RANDOM NUMBER GENERATORS.
00200
00300 RANDH: MOVE @1(RA) ;GET INCREMENT.
00400 FADB 2(RA) ;INCREMENT THE 'POINTER'.
00500 CAML [512.0] ;OVER 512 ?
00600 JRST RNDH2 ;YES. GO GET NEW RANDOM NUMBER.
00700 MOVE T,@(RA) ;NO. GET INPUT ...
00800 FMPR T,3(RA) ;... AND MULT. BY CURRENT RANDOM NO.
00900 JRST 4(RA) ;RETURN.
01000 RNDH2: MOVSI (-512.0) ;CAUSE 'POINTER' TO 'WRAP AROUND'.
01100 FADM 2(RA)
01200 PUSHJ P,RAND ;GET NEW RANDOM NO.
01300 MOVEM T,3(RA) ;MAKE IT THE CURRENT NO.
01400 FMPR T,@(RA) ;MULT. BY INPUT.
01500 JRST 4(RA) ;RETURN.
01600
01700 IRANDI: ;I-TIME CODE FOR RANDI AND RANDH.
01800 IRANDH: PUSHJ P,RAND ;INIT. RANDH.
01900 MOVE T2,(RA) ;GET PTR. TO LAST PARAM..
02000 MOVEM T,-2(T2) ;PUT INITIAL RAND. NO. IN.
02100 JRST 1(RA)
02200
02300 RANDI: MOVE T,2(RA) ;GET CURRENT DELTA..
02400 FADRB T,4(RA) ;ADD TO LAST OUTPUT VALUE...
02500 SOSG 3(RA) ;DECREMENT STEP COUNTER ...
02600 JRST RNDI2 ;IT'S 0, SO GET NEW RANDOM NO.
02700 FMPR T,@(RA) ;NO. MULT BY INPUT.
02800 JRST 5(RA) ;RETURN.
02900 RNDI2: PUSHJ P,RAND ;GET NEXT RANDOM NO.
03000 FSBR T,4(RA) ;FORM DELTA (=NEW - OLD)
03100 MOVSI T1,(512.0)
03200 FDVR T1,@1(RA) ;NO. OF STEPS = 512/(FREQ. INPUT)
03300 FDVR T,T1 ;CHANGE PER STEP =DELTA/NO. OF STEPS
03400 MOVEM T,2(RA) ;STORE CHANGE PER STEP.
03500 FIX T1,233000
03600 ;**********↑↑↑↑↑↑↑
03700 MOVEM T1,3(RA) ;PUT IT AWAY.
03800 JRST RANDI ;NOW GO GENERATE FIRST STEP.
03900
04000 RAND: MOVE T,RNDNO1 ;GENERATE A RANDOM NO.
04100 ADD T,RNDNO2
04200 EXCH T,RNDNO2
04300 MOVEM T,RNDNO1
04400 ASH T,-10 ;SMEAR SIGN INTO EXPONENT FIELD..
04500 FSC T,200 ;... AND FLOAT IT IN RANGE -1 TO 1.
04600 POPJ P,
04700 RNDNO1: 756132257563
04800 RNDNO2: 756132257565
00100 PLIST: BLOCK LPLIST
00200
00300 OSTK: BLOCK LOSTK
00400
00500 RQ1: BLOCK LRQ ;THE RUN QUEUE, CLOUMN ONE.
00600 RQ2: BLOCK LRQ ;COLUMN TWO.
00700
00800 PATCH: BLOCK 100
00900
01000 IARR1: ;; HERE BEGINS AN AREA WHICH IS ZEROED DURING
01100 ; INITIALIZATION OF EACH COMPILATION.
01200
01300 UOTBL: BLOCK LUOTBL
01400
01500 ACS:
01600 RACS: BLOCK 20
01700 IACS: BLOCK 20
01800
01900 UOPTR: -1
02000
02100 IARR2:
02200
02300 PBASE: BLOCK LPA
02400
02500 OUTA: 0 ;CHANNEL A OUTPUT SAMPLE ACCUMULATED HERE.
02600 OUTB: 0 ;CHANNEL B.
02700 OUTC: 0 ;CHANNEL C.
02800 OUTD: 0 ;CHANNEL D.
02900
03000 RDA: 0
03100 RDB: 0
03200 RDC: 0
03300 RDD: 0
03400
03500 IARR3:
03600
03700
03800 VLOC: 0
03900 ILOC: 0
04000 RLOC: 0
04100
04200 DSKMAX: =76*2000*17
00100 ;; THIS IS THE MULTIPLE-FEEDBACK REVERBERATOR.
00200 ;; ITS DELAY TIMES MUST NOT BE R-TIME VARIABLES.
00300
00400 REVX: SOSGE INSXR,15(RA) ; ADVANCE PTR. TO 4TH TAP.
00500 JSP T1,REVX1 ;TIME TO WRAP AROUND....
00600 MOVE T,@16(RA) ;GET DELAY ARRAY OUTPUT FROM 4TH TAP..
00700 FMP T,@10(RA) ;MULT. BY GAIN NO. 4
00800 SOSGE INSXR,14(RA) ;NOW PTR. TO 3RD TAP.
00900 JSP T1,REVX1
01000 MOVE @16(RA) ;... 3RD TAP DELAY OUTPUT...
01100 FMP @6(RA) ;...3RD GAIN...
01200 FAD T,0 ;ACCUMULATE SUM IN T.
01300 SOSGE INSXR,13(RA) ;2ND TAP PTR.
01400 JSP T1,REVX1 ;THIS COULD GET BORING.
01500 MOVE @16(RA)
01600 FMP @4(RA) ;GAIN 2.
01700 FAD T,0
01800 SOSGE INSXR,12(RA) ;ONE MORE CHORUS.
01900 JSP T1,REVX1
02000 MOVE @16(RA)
02100 FMP @2(RA) ;GAIN 1.
02200 FADB T,0 ;T NOW HAS FINAL OUTPUT(=SUM OF
02300 ; TAPS * GAINS).
02400 FAD @(RA) ;ADD OUTPUT TO INPUT ..
02500 SOSGE INSXR,11(RA) ;.. GET PTR. TO INPUT OF DELAY..
02600 JSP T1,REVX1
02700 MOVEM @16(RA) ;AND PUT IT THERE.
02800 JRST 20(RA) ;WOULD YOU BELIEVE 20 PARAMETERS ??!
02900
03000 REVX1: ADD INSXR,17(RA) ;A PTR. HAS UNDERFLOWED; ADD
03100 MOVEM INSXR,@-2(T1) ; LENGTH OF ARRAY TO IT TO WRAP
03200 JRST (T1) ;IT AROUND (AND STORE UPDATED VERSION).
00100
00200 REVXI: MOVE T1,(RA) ;INITIALIZING FOR REVX.. GET PTR. TO PARAMMS.
00300 MOVNI INSXR,1
00400 MOVE @-3(T1) ;GET -1ST ELEMENT OF ARRAY (= ITS LENGTH).
00500 MOVEM -2(T1) ;STORE IN LAST DUMMY PARAM.
00600 SKIPE REVINI ;IF WE ARE INITIALIZING REVERBERATORS,
00700 SETZM -10(T1) ;RESET INPUT PTR. OF DELAY TO BOTTOM OF ARRAY.
00800 MOVSI T,-4 ;NOW WE SET UP THE FOUR DELAY OUTPUT TAP
00900 HRRI T,-7(T1) ;PTRS. THE RIGHT DISTANCE BEHIND THE INPUT PTR.
01000 MOVEI T2,-20(T1) ;
01100 REVXI2: MOVE @(T2) ;PICK UP DELAY TIME (IN SAMPLES).
01200 FIX 233000
01300 ;**********↑↑↑↑↑↑↑↑
01400 ADD -10(T1) ;ADD TO INPUT PTR. POSITION.
01500 CAML -2(T1) ;WRAP AROUND ?
01600 SUB -2(T1) ;YES. SUB. LENGTH OF ARRAY.
01700 MOVEM (T) ;PLACE PTR. IN RIGHT DUMMY PARAM.
01800 ADDI T2,2 ;INC. T2 TO POINT AT NEXT DELAY TIME PARAM.
01900 AOBJN T,REVXI2 ;LOOP TO GET ALL 4 DELAY TAPS.
02000 SKIPN REVINIT ;ARE WE INITIALIZING REVERBERATORS ?
02100 JRST 1(RA) ;NO. RETURN.
02200 MOVE -2(T1) ;YES GET LENGTH OF ARRAY.
02300 HRRZ T,-3(T1) ;GET BASE OF ARRAY.
02400 JRST REVI2 ;GO ZERO ARRAY (SEE REV1 AND REV2 PAGE).
00100 ; ***** COMPX BEGINS HERE **** ROUTINES TO EMIT CODE AND STUFF TO OUTPUT BUFFERS.
00200 EMDV: SETZB A,B ;EMIT A DUMMY VARIABLE (TO RESERVE
00300 ; SPACE IN THE VARIABLES AREA).
00400 EMVCDI: AOS VLOC
00500 EMVCD: MOVEI T1,2 ;EMIT TO VARIABLE BUFFER.
00600 JRST ECD
00700 EMIABS: TDZA B,B ;EMIT TO I-TIME BUF. , NO RELOC.
00800 EMCDI: AOSA RLOC ;SKIP INSTRUCTIONS WIN BIG.
00900 EMICDI: AOSA ILOC ; SEE THE HAPPY INTERLEAVED CODE !
01000 EMCD: TDZA T1,T1 ;EMIT TO RUNTIME BUFFER.
01100 EMICD: MOVEI T1,1 ;EMIT TO INITIALIZE TIME BUFFER.
01200 ECD:
01300 IDPB A,EMPTR(T1) ;EMIT THE WORD.
01400 IDPB B,RELPTR(T1) ;ALSO ITS RELOCATION BITS.
01500 AOSGE BUFCNT(T1) ;IS BUFFER FULL ?
01600 POPJ P, ;NO. RETURN.
01700
01800 GBUF: ; BUFFER IS FULL; GET A NEW ONE.
01900 MOVNI T,LOBUFS ;LENGTH OF A BUFFER.
02000 PUSHJ P,GFS ;GET SOME FREE STORAGE(WHILE IT LASTS!)
02100 HRLI T,400 ;MAKE BYTE PTR.
02200 MOVEM T,RELPTR(T1) ;PTR. FOR RELOCATION BITS.
02300 MOVEI T2,LOBUFS/12+2(T) ;LEAVE ROOM FOR REL. BITS
02400 HRRM T2,EMPTR(T1) ;DATA PTR.
02500 HRRZM T,@OBPTR(T1) ;FIX UP FORWARD LINKS.
02600 HRRZM T,OBPTR(T1)
02700 SETZM @OBPTR(T1)
02800 MOVNI LOBUFS-LOBUFS/12-3
02900 MOVEM BUFCNT(T1) ;SET UP WORD COUNT.
03000 POPJ P,
03100
03200 EMPTR: POINT 36,0,35 ;DATA OUTPUT POINTERS.
03300 EMIPTR: POINT 36,0,35
03400 EMVPTR: POINT 36,0,35
03500 RELPTR: POINT 4,0 ;RELOC. BITS PTRS.
03600 RELIPT: POINT 4,0
03700 RELVPT: POINT 4,0
03800
03900 OBPTR: BLOCK 3 ;PTR. TO FIRST WORD OF CURRENT BUFFER FOR
04000 ; USE IN FIXING UP FORWARD LINKS.
04100 BUFCNT: BLOCK 3 ;WORD COUNTS FOR BUFFERS.
04200
04300 FCBUF: 0 ;PTR. TO FIRST BUFFER IN EACH CHAIN.
04400 FICBUF: 0
04500 FVCBUF: 0
04600
04700 GFS: ADD T,JOBSYM ;DECREMENT BOTTOM OF FREE STORAGE.
04800 HRRZ JOBFF
04900 CAIL (T) ;ROOM LEFT ?
05000 ERROR (STORAGE FULL) ;NO.
05100 MOVEM T,JOBSYM
05200 POPJ P,
00100 ;THIS HERE IS THE COMPILER !
00200 ; RECURSIVE EXPRESSION ANALYZER.
00300
00400 SEXPR: PUSHJ P,SCAN
00500 EXPR: PUSHJ P,TERM ;<EXPR> = <TERM> ! <TERM><ADDOP><EXPR>
00600 EXPR1: TLNE A,DF ;A DELIMITER NEXT ?
00700 TLNN A,ADDBIT ;YES. AN ADD OR SUBTRACT OP. ?
00800 POPJ P, ;NO.
00900 PUSH P,A ;YES. LOOK FOR ANOTHER TERM.
01000 PUSHJ P,STERM ;THIS IS ITERATIVE INSTEAD OF
01100 ; RECURSIVE IN ORDER TO PROCESS FROM LEFT TO
01200 EXCH A,(P) ; RIGHT.
01300 PUSHJ P,(A) ;CALL APPROPRIATE GENERATOR.
01400 POP P,A
01500 JRST EXPR1
01600
01700 STERM: PUSHJ P,SCANV
01800 TERM: PUSHJ P,FACTOR ;<TERM>=<FACTOR>!<FACTOR><MULOP><FACT.>
01900 TERM1: TLNE A,DF ;A DELIMITER NEXT ?
02000 TLNN A,MULBIT ;YES. A MULTIPLY OR DIVIDE OP ?
02100 POPJ P, ;NO.
02200 PUSH P,A
02300 PUSHJ P,SFACTOR
02400 EXCH A,(P)
02500 PUSHJ P,(A)
02600 POP P,A
02700 JRST TERM1
02800
02900 SFACTOR:PUSHJ P,SCANV
03000 FACTOR: JRST PRIMARY ;GOOD ENOUGH FOR NOW ...
03100
03200 SPRIM: PUSHJ P,SCAN
03300 PRIMARY:
03400 JUMPE A,UDIERR ;STILL UNDEFINED ?
03500 TLNN A,DF ;IS IT A SPECIAL CHAR. ?
03600 JRST PRIM3 ;NO.
00100 PRIM2: CAMN A,MINV ;UNARY MINUS ?
00200 JRST PRUMIN ;YES.
00300 CAME A,LPARV ;NO. IT BETTER BE A (.
00400 ERROR (ILLEGAL PRIMARY.)
00500 PUSHJ P,SEXPR ;SCAN AN EXPRESSION.
00600 CAME A,RPARV ;LOOK FOR MATCHING PAREN.
00700 ERROR (MISSING RIGHT PAREN.)
00800 JRST SCAN ;SCAN AND RETURN.
00900
01000 PRUMIN: PUSHJ P,SPRIM ;UNARY MINUS; SCAN A PRIMARY.
01100 PUSH P,A
01200 PUSHJ P,UMGEN ;CALL GENERATOR.
01300 JRST POPAJ ;RESTORE A AND RETURN.
01400
01500 PRIM3: TLNN A,FUNBIT ;THE NAME OF A FUNCTION ?
01600 JRST SVRBL ;NO.
01700 PRFUN: PUSHJ P,FUNCAL ;COMPILE THE FUNCTION CALL.
01800 PUSHJ P,MRKAC0 ;MARK AC0 FULL (VALUE OF FUNCTION).
01900 JRST SCAN ;RETURN.
02000
02100 SVRBL: TLNN A,VRBLBT!SWVBT!NUMFLG!FOOBIT ;SHOULD BE A VARIABLE,ARRAY NAME,NUMBER OR FOO SYM.
02200 ERROR (ILLEGAL PRIMARY)
02300 TLNE A,VRBLBT!NUMFLG!FOOBIT ;IS IT AN ARRAY NAME ?
02400 JRST SVRBL2 ;NO.
02500 HRR A,(A) ;YES. GET R. HALF OF GOOD BITS.
02600 SUBI A,2 ;MAKE IT POINT TO ARRAY[-2].
02700 SVRBL2: PUSH OSP,A ;MAY BE AN ASN. STMT....
02800 TLNE A,NUMFLG+SWVBT ;IF IT IS A NUMBER, IT CAN'T BE
02900 JRST SCAN ;LEFT PART OF ASN. STMT.
03000 SVRBL1: PUSHJ P,SCAN ;GET LEFT ARROW,IF ANY.
03100 CAME A,LARV ;IT IS ONE, ISN'T IT ?
03200 LAROW: POPJ P, ;NOPE. JUST A GARDEN VARIETY VARIABLE.
03300 PUSHJ P,ASTMT1 ;YES. COMPILE IT.
03400 PUSHJ P,MRKAC ;SINCE ITS A PRIMARY, REMEMBER ITS
03500 JRST POPAJ ;VALUE, THEN RETURN.
03600 ASTMT1: ;; COMPILE ASSIGNMENT STMT...
03700 PUSHJ P,SEXPR ;COMPILE RIGHT PART OF STMT.
03800 EXCH A,(P) ;SAVE 'A' UNDERNEATH RETURN ADR.
03900 PUSH P,A
04000 JRST ASNGEN ;GENERATE THE STORE.
00100 ; PROCESS A FUNCTION CALL.
00200
00300 FUNCAL: PUSH P,RLOC ;SAVE R-TIME CODE LOC. CTR.
00400 HRRZ B,(A) ;GET PTR. TO PARAMETER DESCRIPTORS.
00500 PUSH P,B ;PTR. TO SYMTABLE ENTRY.
00600 PUSH OSP,(B) ;PLACE CALLING INSTR. ON OPND. STK.
00700 PUSH P,[POINT 6,0,35] ;MAKE A PTR. TO THE BYTES
00800 HRRM B,(P) ; OF THE PARAMETER DESRIPTION.
00900 ILDB T,(P) ;GET PARAMTER COUNT.
01000 PUSH P,T
01100 JUMPE T,FNOPR ;IF NO PARAMS., CALL GENERATOR.
01200 PUSHJ P,SCAN ;SWALLOW LEFT PAREN.
01300 CAME A,LPARV ;I HATE PEOPLE WHO DO THIS.
01400 ERROR (MISSING LEFT PAREN.)
01500 PUSHJ P,SCAN ;SCAN FIRST PARAM.
01600 FUNC4: PUSH P,A
01700 FUNC1: ILDB T,-2(P) ;GET NEXT PARAM. DESCRIPTOR.
01800 CAIN T,FDPARB ;IS IT A DUMMY PARAM. ?
01900 JRST FDPAR ;YES.
02000 CAIN T,FDPARC ;OR A TYPE 2 DUMMY ?
02100 JRST FDPAR2 ;YES.
02200 POP P,A ;NO.
02300 JUMPE T,FLPAR ;IF =0,NO MORE PARAMS.
02400 CAME A,RPARV ;NO PARENTHESES OR COMMAS HERE, PLEASE.
02500 CAMN A,COMMAV
02600 ERROR (MISSING PARAMETER)
02700 CAIN T,FAOPAR ;MUST THIS PARAM. BE AN ARRAY NAME ?
02800 JRST FAPAR ;YES.
02900 PUSHJ P,EXPR ;NO, LET IT BE AN EXPRESSION.
03000 FUNC2: CAMN A,COMMAV ;IS IT A COMMA ?
03100 FUNC3: PUSHJ P,SCAN ;YES, ALTHOUGH WE DONT REALLY CARE.
03200 JRST FUNC4
03300
03400 FLPAR: CAME A,RPARV ;LAST PARAM. IS FOLLOWED BY ).
03500 ERROR (MISSING RIGHT PAREN.) ; ... OR ELSE.
03600 FNOPR: PUSHJ P,GFUNC ;CALL GENERATORS.
03700 ILDB A,-1(P) ;GET NO. OF AC CONTAINING RESULT.
03800 SUB P,[XWD 4,4] ;FORGET ABOUT THINGS IN STACK.
03900 POPJ P,
04000
04100 FAPAR: ;PARAMETER IS NAME OF FUNCTION ARRAY.
04200 PUSHJ P,GAPAR ;CALL GENERATOR.
04300 PUSHJ P,SCAN
04400 JRST FUNC2
04500
04600 FDPAR: PUSHJ P,GDPAR ;GENERATE A DUMMY PARAM.
04700 JRST FUNC1
04800 FDPAR2: PUSH OSP,[0] ;EMIT A DUMMY PARAM., BUT WITHOUT
04900 JRST FUNC1 ;ANY INSTR. TO ZERO IT AT I-TIME.
00100 ; HERE ARE THE GLORIOUS, SUPER-INTELLIGENT, SCHIZOPHRENIC
00200 ; CODE GENERATORS. LOOK UPON THEM AND BE AMAZED.
00300
00400 MULGEN: SKIPA T,[FMP] ;GENERATE A MULTIPLY.
00500 ADDGEN: MOVSI T,(<FAD>) ;SEE THE STUPID FAIL !
00600 PUSH P,T
00700 PUSHJ P,GGET1 ;GET ONE OPERAND IN AN AC.
00800 GEN1: POP P,C ;RECOVER THE OPCODE.
00900 GEN2: PUSHJ P,EMINST ;EMIT THE INSTRUCTION.
01000 JRST MRKAC ;MARK THE AC FULL AND RETURN.
01100
01200 DIVGEN: SKIPA T,[FDV] ;GENERATE A DIVIDE ...
01300 SUBGEN: MOVSI T,(<FSB>) ; .. OR A SUBTRACT.
01400 PUSH P,T
01500 PUSHJ P,GGET2 ;GET FIRST OPERAND IN AN AC.
01600 JRST GEN1
01700
01800 UMGEN: PUSHJ P,GMURKA ;UNARY MINUS. GET THE OPERAND.
01900 PUSH P,E
02000 PUSHJ P,GETAC ;GET A FREE AC.
02100 POP P,B ;BRING BACK AC ADDRESS.
02200 MOVSI C,(<MOVN>) ;EMIT GOOD INSTRUCTION.
02300 JRST GEN2
02400
02500 MULOP←←MULGEN
02600 ADDOP←←ADDGEN
02700 SUBOP←←SUBGEN
02800 DIVOP←←DIVGEN
02900
03000 ASNGEN: ;COMPILE STORE FOR ASIGNMENT STMT.
03100 ASNOP: PUSH P,-1(OSP) ;SAVE PTR. TO GOOD BITS OF VRBL.
03200 PUSHJ P,GMURK ;GET EXPR. AND LEFT-PART VARIABLE.
03300 EXCH D,E ;GET THEM IN RIGHT ORDER.
03400 PUSHJ P,GG2 ;GET EXPR. IN AN AC.
03500 POP P,T ;RECOVER PTR. TO VRBL. GOOD BITS WORD...
03600 MOVE H
03700 LSH =35-PRVBT ;PUT R-TIME FLAG IN RIGHT POSITION...
03800 TLNN B,GPBIT ;IF NOT A P-SYMBOL,
03900 ORM (T) ;SET R-TIME BIT CORRECTLY.
04000 MOVSI C,(<MOVEM>) ;EMIT A MOVEM TO STORE VALUE OF EXPR.
04100 JRST EMINST
04200
00100 ; HA! I BET YOU THOUGHT WE WERE DONE, DIDN'T YOU ?
00200
00300 ; WELL, HERE BEGINS AN INFINITE REGRESSION OF
00400 ; CLEVER ,GRUBBY ROUTINES WHICH DO THE
00500 ; DIRTY WORK FOR THE GENERATORS.
00600
00700 ; GPONDER REMOVES THE TOP THING FROM THE OPERAND STACK,
00800 ; LOVINGLY PATS ITS MAGIC BITS INTO STANDARD FORMAT,
00900 ; AND SETS A FLAG INDICATING WHETHER IT IS AN
01000 ; R-TIME VARIABLE OR NOT.
01100
01200 GPONDER: MOVEI H,0 ;RESET R-TIME VARIABLE FLAG.
01300 GPOND1: POP OSP,T ;GET TOP THING.
01400 TLNE T,FOOBIT ;IS IT A FOO-SYMBOL?
01500 JRST GPFOO ;YES.
01600 TLNE T,NUMFLG ;A NUMBER ?
01700 POPJ P, ;YES. WE ARE DONE.
01800 TLNE T,SRACBT+RVBT ;AN R-TIME AC OR VARIABLE ?
01900 MOVEI H,1 ;YES. SET R-TIME FLAG.
02000 TLNE T,SRACBT ;AN R-TIME AC ?
02100 SETZM RACS(T) ;YES. MARK IT FREE.
02200 TLNE T,SIACBT ;(SAME FOR I-TIME AC).
02300 SETZM IACS(T)
02400 TLNE T,VRBLBT ;A VARIABLE ?
02500 HRR T,(T) ;YES. GET RT. HALF GOOD BITS.
02600 POPJ P,
02700 GPFOO: TRZE T,400000 ;IS IT A P-SYMBOL?
02800 JRST GPONP ;YES.
02900 GPONU: MOVEI H,1 ;REFERS TO A UINIT GENERATOR; SET FLG.
03000 HRRZS T ;GET NO. OF UNIT GEN.
03100 CAMLE T,UOPTR ;NO FORWARD REFERENCES TO UNIT GEN.
03200 ERROR (FORWARD REF. TO UNIT GENERATOR)
03300 MOVE T,UOTBL(T) ;GET ADDRESS OF ITS OUTPUT CELL.
03400 POPJ P,
03500
03600 GPONP:
03700 ADDI T,PBASE ;BASE OF PARAM. ARRAY.
03800 HRLI T,GPBIT ;MARK AS P-SYMBOL.
03900 POPJ P,
04000
00100 ; GMURK CLEVERLY GPONDERS THE TOP TWO OPERANDS,
00200 ; AND IF ONE OF THEM IS AN R-TIME VARIABLE
00300 ; AND THE OTHER IS AN I-TIME AC OR A P-SYMBOL, IT STORES
00400 ; THE LATTER WHERE IT WILL BE SAFE UNTIL R-TIME.
00500
00600 GMURKA: MOVEI H,0
00700 GMURK1: TDZA T,T ;PROCESS ONLY TOP STACK ELEMENT.
00800 GMURK: PUSHJ P,GPONDER ;GPONDER THE FIRST OPERAND.
00900 PUSH P,T ;SAVE IT
01000 PUSHJ P,GPOND1 ;NOW THE SECOND.
01100 POP P,D ;PUT THEM BOTH IN SOME SAFE ACCUMULATORS.
01200 MOVE E,T
01300 SKIPN H ;IS EITHER ONE AN R-TIME VARIABLE ?
01400 POPJ P, ;NO.
01500 TLNE E,SIACBT+GPBIT ;AN I-TIME AC OR A P-SYMBOL ?
01600 JRST GM2 ;YES.
01700 TLNN D,SIACBT+GPBIT ;HOW ABOUT THIS ONE ?
01800 POPJ P, ;HE ISN'T, EITHER. RETURN.
01900 SKIPA F,[EXP D] ;BAGBITING MACROX.
02000 GM2: MOVEI F,E ;SEE THE TWO HEADED MONSTER.
02100 MOVE A,(F) ;GET THE RELEVANT THING.
02200 TLNE A,GPBIT ;A P-SYMBOL, OR AN I-TIME AC ?
02300 JRST GM3 ; A P-SYMBOL.
02400 MOVE B,VLOC ;STORE IT IN VARIABLE AREA.
02500 GM3B: MOVEM B,(F) ;CHANGE THE OPERAND INDICATOR.
02600 MOVE C,[MOVEM EMICDI] ;EMIT THE STORE INSTRUCTION.
02700 PUSHJ P,EMINST
02800 JRST EMDV ;MAKE APLACE IN THE VARIABLES FOR IT.
02900
03000 GM3: SKIPN T1,(A) ;HAS THE PARAMETER ALREADY BEEN
03100 JRST GM3A ; PUT IN VAR. AREA ?
03200 MOVEM T1,(F) ;YES. CHANGE POINTER.
03300 POPJ P,
03400
03500 GM3A: PUSHJ P,GETIAC ;FIND FREE I-TIME AC.
03600 MOVE B,(F)
03700 MOVE T,VLOC ;GET VAR. LOC. CTR.
03800 TLO T,GPBIT
03900 MOVEM T,(B) ;ENTER IN PARAMTER TABLE.
04000 MOVE C,[MOVE EMICDI] ;EMIT INSTR. TO
04100 PUSHJ P,EMINST ;PICK UP THE PARAMETER.
04200 MOVE B,VLOC ;GET LOC. AGAIN...
04300 TLO B,GPBIT ;MARK AS A P-SYMBOL.
04400 JRST GM3B ;NOW STORE THE PARAMETER IN VAR. AREA.
04500
00100 ; STILL MORE KLUGES. PAUSE TO GET YOUR BREATH NOW.
00200
00300 ;GGET1 ARRANGES TO HAVE ONE OF THE TOP TWO OPERANDS
00400 ; IN AN AC. IT RETURNS IN 'A' THE ADDRESS OF THAT AC, AND
00500 ; IN 'B' THE ADDRESS OF THE OTHER OPERAND, WITH RELOCATION
00600 ; BITS IN LEFT HALF.
00700
00800 GGET1: PUSHJ P,GMURK ;PROCESS TOP TWO OPERANDS.
00900 TLNN D,SIACBT+SRACBT ;IS FIRST ONE IN AN AC ?
01000 JRST GG2 ;NO.
01100 MOVE A,D ;YES. WE ARE DONE.
01200 MOVE B,E
01300 POPJ P,
01400 GGET2: PUSHJ P,GMURK ;GGET2 GETS SECOND OPERAND IN AN AC.
01500 GG2: MOVE A,E ;PUT OPERAND IN A.
01600 TLNE A,SIACBT+SRACBT ;IS IT ALREADY IN AN AC ?
01700 JRST GL2A ;YES. WIN BIG.
01800 TLNE D,SIACBT+SRACBT ;HOW ABOUT OTHER OP. ?
01900 SETOM @ACTB3(H) ;AN AC... MARK IT FULL TEMPORARILY.
02000 PUSHJ P,GETAC ;GET A FREE AC OF THE APPROPRIATE KIND.
02100 MOVE B,E ;LOAD SECOND OPERAND INTO IT.
02200 MOVSI C,(<MOVE>) ;EMIT LOAD INSTR.
02300 PUSHJ P,EMINST
02400 TLNE D,SIACBT+SRACBT ;IF OTHER OP. IS IN AN AC,
02500 SETZM @ACTB3(H) ;MARK IT FREE NOW.
02600 GL2A: MOVE B,D ;PUT OTHER OP IN B.
02700 POPJ P,
02800
02900 ; EMINST IS THE INSTRUCTION EMITTING ROUTINE. CALL IT
03000 ; WITH AC IN A,THE ADDRESS (+ RELOC. BITS) IN B, AND
03100 ; OPCODE IN C. IF RIGHT HALF OF C IS NON-ZERO, IT IS THE
03200 ; ADDRESS OF THE APPROPRIATE BUFFER EMITTING ROUTINE;
03300 ; OTHERWISE THE INSTR. IS PLACED IN THE I-TIME
03400 ; OR R-TIME BUFFERS ACCORDING TO THE STATE OF THE FLAG IN H.
03500
03600 EMINST: PUSH P,A ;SAVE IT.
03700 HLL A,C ;ASSEMBLE INSTRUCTION IN A.
03800 DPB A,[POINT 4,A,12] ;PUT IN AC FIELD.
03900 HRR A,B ;ALSO ADDRESS.
04000 TLZE B,FPARBT ;IS ADDR. A FORMAL PARAMETER ?
04100 TLO A,20+RA ;YES. ADD INDIRECT BIT AND INDEX.
04200 HLRZS B ;PUT RELOC. BITS FOR ADDRESS IN RIGHT HALF OF B.
04300 PUSH P,[EXP EMIN2] ;RETURN ADDRESS.
04400 TRNE C,-1 ;RH OF C =0 ?
04500 JRST (C) ;NO.
04600 JRST @EMITB(H)
04700 POPAJ: ;A USEFUL ENTRY POINT.
04800 EMIN2: POP P,A
04900 POPJ P,
05000 EMITB: EMICDI
05100 EMCDI
05200 ACTB3: XWD D,IACS
05300 XWD D,RACS
00100 ;GETAC SEARCHES FOR A FREE AC, EITHER I-TIME OR
00200 ; R-TIME, AS INDICATED BY THE STATE OF THE FLAG IN H.
00300
00400 GETAC: SKIPE H ;ARE WE EMITTING R-TIME CODE ?
00500 GETRAC: SKIPA T3,[XWD SRACBT+A,RACS] ;YES, FIND A R-TIME AC.
00600 GETIAC: MOVE T3,[XWD SIACBT+A,IACS] ;FIND AN I-TIME AC.
00700 MOVE A,[XWD -NACS,NFACS] ;CONSIDER ONLY AC'S 4-14
00800 TRNE FL,CSBRBT ; ..UNLESS WE'RE COMPILING A FUNCTION..
00900 MOVE A,[XWD -NFACS,0] ;WE ARE. CONSIDER ONLY 0-3.
01000 SKIPE @T3 ;INDIRECT ADDRESSING IS GOOD FOR YOU.
01100 AOBJN A,.-1 ;NOT FREE. TRY FOR NEXT ONE.
01200 JUMPLE A,GETAC3 ;DID WE FIND ONE ?
01300 PUSHJ P,GETAC2 ;NO. STORE ONE.
01400 GETAC3: HRLI A,SRACBT ;YES. PUT IN APPROPRIATE FLAG BITS.
01500 TLNN T3,SRACBT ;OOPS, IT'S AN I-TIME AC.
01600 HRLI A, SIACBT
01700 POPJ P,
01800
01900 GETAC2: SUBI A,1 ;STORE HIGHEST AC.
02000
02100 GSVAC: MOVE T,@T3 ;FIND OUT WHO'S IN HIM.
02200 MOVE B,VLOC ;GET LOC. TO STORE HIM IN.
02300 MOVEM B,(T) ;FIX UP HIS STACK ENTRY.
02400 SETZM @T3 ;MARK HIM EMPTY.
02500 MOVSI C,(<MOVEM>) ;EMIT THE STORE INST.
02600 PUSHJ P,EMINST
02700 JRST EMDV ;LEAVE A PLACE IN VARIABLES AREA.
02800
02900 ;MRKAC PUTS THE AC SYMBOL IN A BACK ON THE STACK AND MARKS
03000 ; THE CORRESPONDING AC AS FULL.
03100
03200 MRKAC0: IOR A,MRKTAB(H) ;MARK IAC 1 OR RAC 1 FULL.
03300
03400 MRKAC: PUSH OSP,A ;PUT IT ON STACK.
03500 TLNN A,SRACBT ;AN R-TIME AC?
03600 HRRZM OSP,IACS(A) ;NO, MARK CORRESPONDING I-TIME AC FULL.
03700 TLNE A,SRACBT
03800 HRRZM OSP, RACS(A)
03900 CPOPJ: POPJ P,
04000
04100 MRKTAB: XWD SIACBT,0 ;DESCRIPTOR FOR I-TIME AC NO. 1
04200 XWD SRACBT,0 ;R-TIME AC 1.
04300
00100 ;; MORE GENERATORS.
00200
00300 GAPAR: ;; HANDLE A PARAMETER WHICH IS AN ARRAY NAME.
00400 TLNE A,SWVBT ;IS IT AN ARRAY IDENTIFIER OR
00500 HRR A,(A)
00600 TLNE A,FPARBT+SWVBT ; A FORMAL PARAMETER ?
00700 JRST GAPR1 ;YES.
00800 TLNE A,FOOBIT ;BETTER BE A FOO-SYMBOL, THEN....
00900 TRZN A,400000 ;FURTHERMORE, IT MUST BE A P-SYM.
01000 ERROR(IMPROPER ARRAY PARAMETER)
01100 PUSH P,A ;SAVE P NO.
01200 PUSHJ P,GETIAC ;FIND FREE I-TIME AC.
01300 POP P,B
01400 ADDI B,PBASE ;CALC. ADDR. OF P-SYMBOL.
01500 MOVE C,[MOVE EMICDI] ;EMIT MOVE AC,P-SYMBOL TO THE
01600 PUSHJ P,EMINST ;I-TIME CODE STREAM.
01700 HRLI A,(<MOVEM>) ;NOW A MOVEM AC, INTO THE PARAMETER
01800 DPB A,[POINT 4,A,12] ;LOCATION.
01900 TRZA A,-1 ;CLEAR ADDRESS FIELD.
02000 GDPAR: MOVSI A,(<SETZM>) ;PARAM. LIST AT I-TIME.
02100 PUSH OSP,ILOC ;PUT ARRAY MARKER IN OPERAND
02200 MOVSI T,SWVBT+FPARBT ;STACK SO A FIXUP CAN BE EMITTED TO
02300 IORM T,(OSP) ;THE UPCOMMING HRRM WHEN THE PARAMETERS
02400 MOVEI B,0 ;NO RELOCATION, PLEASE.
02500 JRST EMICDI ;EMIT HRRM TO STORE ARRAY LOC. INTO
02600 ;PARAMETER CELL, AND RETURN.
02700 GAPR1: PUSH OSP,A ;PLACE IN OPERAND STACK.
02800 POPJ P,
00100 GFUNC: ;; GENERATE A FUNCTION CALL.
00200 MOVE A,@-3(P) ;PICK UP THE CALLING INSTR. FOR THE FUNCTION.
00300 MOVE D,RLOC ;DECIDE WHETHER CALL IS TO BE IN
00400 MOVEI H,0 ;R-TIME OR I-TIME CODE.
00500 TLZN A,20 ;IND. BIT IN INSTR. SAYS R-TIME ALWAYS.
00600 CAME D,-4(P) ;ALSO R-TIME IF ANY R-TIME PARAMETERS
00700 MOVEI H,1 ;HAVE BEEN COMPILED.
00800 GFUNC8: MOVE T3,ACTB1(H)
00900 MOVSI A,-NFACS ;PREPARE TO SEARCH AC'S 0-4.
01000 SKIPN T,@T3 ;IS THIS ONE IN USE ?
01100 AOBJN A,.-1 ;NO.
01200 JUMPG A,GFUNC6 ;DID WE FIND A BUSY ONE ?
01300 PUSHJ P,GSVAC ;YES. SAVE IT.
01400 JRST GFUNC8
01500 GFUNC6: PUSH P,-1(P) ;PUT PAR. COUNT ON STACK.
01600 HRRZM P,TEMP1# ;SAVE LOC. OF COUNT.
01700 GFUNC5: SOSGE @TEMP1 ;MORE PARAMS ?
01800 JRST GFUNC4 ;NO.
01900 PUSHJ P,GMURK1 ;GET A PARAM.
02000 TLNN E,SWVBT
02100 TLNN E,FPARBT ;IS IT A FORMAL PARAMETER ?
02200 JRST GFUNC7 ;NO, THANK GOD.
02300 MOVE A,E ;SIGH. THE PRICE OF HONESTY ...
02400 HRLI A,(<MOVE (RA)>) ;EMIT CODE TO PICK UP THE
02500 MOVEI B,0 ;PARAM. PTR. AND PUT IT IN THE
02600 PUSHJ P,@EMITB(H) ;CURRENT CALLING SEQUENCE.
02700 MOVE E,ILOC(H) ;SAVE ILOC OR RLOC FOR LATER FIXUP.
02800 TLO E,FPARBT ;MIGHT AS WELL USE THIS BIT...
02900 MOVSI A,(<MOVEM>) ;NOW THE SECOND INSTR....
03000 PUSHJ P,@EMITB(H)
03100 GFUNC7: PUSH P,E ;SAVE IT.
03200 JRST GFUNC5 ;GET ANOTHER.
03300 GFUNC4: POP OSP,A ;NOW EMIT THE CALLING INSTR.
03400 GFUNC2: LDB B,[POINT 4,A,17] ;RELOC. BITS.
03500 TLZ A,37
03600 TLZE A,SWVBT ;IS IT AN ARRAY NAME ?
03700 TLO A,INSXR ;YES. ADD INDEX FIELD.
03800 GFUNC3: PUSHJ P,@EMITB(H) ;
03900 POP P,A ;GET PARAM. FROM STACK.
04000 JUMPL A,CPOPJ ;IF IT'S THE MARK, RETURN.
04100 TLZN A,FPARBT ;IS IT A FORMAL PARAMETER ?
04200 JRST GFUNC2 ;NO. EMIT IT.
04300 MOVEI B,.FXBTS ;YES. EMIT A FIXUP TO THE RIGHT INSTRUCTION.
04400 TLZ A,400000+LRFXBT+SWAPBT ;A REPLACEMENT FIXUP TO RT. HALF.
04500 TLO A,RRFXBT
04600 PUSHJ P,@EMITB2(H) ;EMIT IT TO I-TIME OR R-TIME BUFER.
04700 MOVEI B,0 ;NOW RESERVE SPACE FOR THE PARAM.
04800 JRST GFUNC3
04900 EMITB2: EMICD
05000 EMCD
05100 ACTB1: XWD SIACBT+A,IACS ;PTR. TO IACS,INDEXED BY B.
05200 XWD SRACBT+A,RACS
00100 ;; UTILITY RUOTINE TO ENTER AN ITEM IN THE MAIN SYMBOL TAB.
00200
00300 GETNAM: PUSHJ P,SCANV ;SCAN AN IDENTIFIER.
00400 GETNM1: AOS T,(P) ;TO SKIP PARAM ON RETURN.
00500 JUMPE A,GNM2 ;SHOULD BE UNDEFINED...
00600 TLOE A,DF ;IT'S NOT. MAYBE IT'S A DELIMITER ?
00700 ERROR (MISSING IDENTIFIER)
00800 TLNN A,@-1(T) ;NO. MAYBE ALREADY RIGHT TYPE ?
00900 ERROR (MULTIPLY DEFINED SYMBOL)
01000 SKIPGE -1(T) ;AH, IT IS. SHOULD WE REENTER IT ?
01100 POPJ P, ;NO. ITS OLD ENTRY WILL DO.
01200 GNM2: HRLZ A,-1(T) ;YES. GET TYPE BITS.
01300
01400 AENTER: HRRZ JOBFF ;GET NEXT FREE LOCATION.
01500 HRRZ B,CBNO ;GET BUCKET NO. OF THING JUST SCANNED.
01600 EXCH BUCTBL(B) ;UPDATE BUCKET HEAD.
01700 AOS B,JOBFF
01800 MOVEM -1(B) ;PUT THE LINK IN THE NEW ENTRY.
01900 MOVEM A,1(B) ;PUT THE RANDOM GOOD BITS IN.
02000 MOVE ACCUM ;GET FIRST WORD OF NAME.
02100 MOVEM (B) ;PUT IN TABLE.
02200 AOS B,JOBFF
02300 MOVEI T,ACCUM+1 ;PREPARE TO MOVE REST OF NAME.
02400 AEL1: AOS JOBFF
02500 SKIPN T1,(T) ;ANY MORE OF THE NAME ?
02600 JRST AEL2 ;NO.
02700 MOVEM T1,@JOBFF ;YES. PUT IN TABLE.
02800 CAIL T,ACCUM+2 ;UNLESS FIRST OR SECOND WORD,
02900 SETZM (T) ;ZERO WORD IN ACCUM.
03000 AOJA T,AEL1
03100 AEL2: HRRZ JOBSYM ;GET BOTTOM OF BUFFER AREA.
03200 CAMG JOBFF ;HAVE WE OVERRUN IT ?
03300 ERROR(CORE IS FULL)
03400 HRR A,B
03500 HRRZ JOBFF
03600 HRLM JOBSA
03700 POPJ P,
03800
00100 ;; INITIALIZATION OF THE COMPILER.
00200
00300 EXTERNAL JOBFF,JOBSA
00400 JOBSYM: 0
00500
00600 SCOMPA: MOVE OSP,[XWD -LOSTK,OSTK-1] ;INIT. OPERAND STACK.
00700 PUSH OSP,JOBSYM ;...SO WE CAN RESTORE IT LATER.
00800 MOVSI IRELBT ;INIT THE THREE LOCATION
00900 MOVEM ILOC ;COUNTERS (APPROPRIATE RELOCATION
01000 MOVSI RRELBT ;BITS LIVE IN LEFT HALF OF EACH).
01100 MOVEM RLOC
01200 MOVSI VRELBT
01300 MOVEM VLOC
01400 MOVEI T1,2 ;SET UP THE THREE CHAINS OF OUTPUT
01500 SCMP1: SETZM OBPTR(T1)
01600 PUSHJ P,GBUF ;BUFFERS.
01700 HRRZM T,FCBUF(T1) ;PTR. TO FIRST BUFFER OF CHAIN
01800 SOJGE T1,SCMP1 ;DO FOR ALL THREE CHAINS.
01900 SETZM IARR1 ;ZERO SOME TABLES AND STUFF.
02000 MOVE [XWD IARR1,IARR1+1]
02100 BLT IARR2-1
02200 MOVEI FL,0 ;CLEAR FLAGS.
02300 POPJ P,
02400
02500 SCOMP: PUSHJ P,SCOMPA ;INIT. THE COMPILER.
02600 MOVE [XWD IARR2-1,IARR2]
02700 BLT IARR3-1 ;ZERO REST OF TABLES.
02800 POPJ P,
00100 ;; SYNTAX ANALYZER.
00200
00300 SSTATL: PUSHJ P,SMCSCN ;SCAN NEXT NON-SEMICOLON.
00400 STATL: CAMN A,FINV ;IS IT A FINISH ?
00500 JRST ENDP1 ;YES.
00600 PUSHJ P,STAT ;NO. SCAN A STATEMENT.
00700 JRST SSTATL ;GO BACK FOR MORE.
00800
00900 SSTAT: PUSHJ P,SMCSCN
01000 STAT: MOVEI H,0 ;CLEAR 'R-TIME CODE' FLAG.
01100 JUMPGE A,STAT2 ;A DELIMITER ?
01200 TLNE A,DECLBIT ;YES. A DECLARATION ?
01300 JRST (A) ;YES. DISPATCH TO RIGHT ROUTINE.
01400 STAT2: PUSHJ P,STMT1 ;IT HAS TO BE A STMT1.
01500 STATL1: CAME A,SEMICV ;SEMICOLON AFTER EVERY STMT.,PLEASE.
01600 ERROR (MISSING SEMICOLON) ;I HATE MYSELF FOR THIS.
01700 TDZ FL,[XWD ERRFLG,EXTFLG] ;TURN OFF ERROR FLAG.
01800 POPJ P, ;END OF STATEMENT.
01900
02000 EXTD: PUSHJ P,SCAN ;"EXTERNAL" DECLARATION.
02100 CAME A,FUNV ;BETTER BE "FUNCTION".
02200 ERROR (<EXTERNAL FUNCTIONS ONLY,PLEASE.>)
02300 TRO FL,EXTFLG ;SET FLAG.
02400 JRST DFUNC
02500
02600 SSTMT1: PUSHJ P,SCAN
02700 STMT1: SKIPN A ;IS IT UNDEFINED ?
02800 ERROR (UNDEFINED IDENTIFIER)
02900 STMT1A: TLNE A,FUNBIT ;<STMT1>=<FUNCTION CALL> ! <ASN. STMT>
03000 JRST SFUNC ;A FUNCTION CALL.
03100 TLNN A,VRBLBT!FOOBIT ;BETTER BE A SIMPLE VARIABLE.
03200 ERROR (SIMPLE VARIABLE REQUIRED HERE.)
03300 PUSH OSP,A ;STACK IT.
03400 PUSHJ P,SCAN ;GET LEFT ARROW.
03500 CAME A,LARV
03600 ERROR (ILLEGAL STATEMENT)
03700 PUSHJ P,ASTMT1 ;IT'S AN ASSIGNMENT STMT. COMPILE IT.
03800 JRST POPAJ ;RESTORE A(WHICH WAS SAVED BY ASTMT)
03900 ; AND RETURN.
04000 SFUNC: PUSHJ P,FUNCAL ;COMPILE FUNCTION CALL
04100 JRST SCAN ;RETURN.
04200
04300 SMSC1:
04400 SMCSCN: PUSHJ P,SCAN ;SCAN PAST NEXT SEMICOLON.
04500 SMCS1: CAMN A,SEMICV
04600 JRST SMCSCN
04700 POPJ P,
00100
00200 ENDSTL: RELEAS DT, ;ALL DONE. RELEAS INPUT DEVICE.
00300 ENDP1:
00400 MOVEI A,0
00500 MOVEI B,.FXBTS ;PUT END MARKS IN THE BUFFERS.
00600 PUSHJ P,EMCD
00700 PUSHJ P,EMICD
00800 PUSHJ P,EMVCD
00900 POP OSP,JOBSYM ;RESTORE JOBSYM.
01000 POPJ P,
01100 EXTERNAL JOBDDT,JOBREL
01200
01300 DVRBL1: CAME A,COMMAV ;IS IT A COMMA ?
01400 JRST STATL1 ;NO. END OF DECL.
01500 DVRBL: PUSHJ P,SCAN ;GET NEXT ITEM.
01600 CAMN A,CTBL+"/" ;IS IT A "/" ?
01700 JRST DVRBL2 ;YES. DEFINE FOLLOWING VARIABLE AS R-TIME.
01800 PUSHJ P,GETNM1 ;NO. MUST BE NAME OF VARIABLE. PUT IN SYM. TABLE.
01900 XWD 400000,VRBLBT ;PARAM. TO GETNM1.
02000 DVRBL4: JUMPL A,DVRBL3 ;WAS IT ALREADY DEFINED ?
02100 AOS A,JOBFF ;NO, IT'S NEW. LEAVE WORD FOR THE VALUE.
02200 SUBI A,1 ;GET PTR. TO THAT WORD.
02300 HRRM A,(B) ;PUT IN GOOD BITS WORD (NO REL. BITS).
02400 DVRBL3: PUSHJ P,SCAN ;GET COMMA OR SEMICOLON.
02500 JRST DVRBL1 ;BACK FOR MORE.
02600
02700 DVRBL2: PUSHJ P,GETNAM ;SCAN AND ENTER NAME OF VARIABLE.
02800 XWD 400000,VRBLBT!RVBT ;INCLUDE 'R-TIME' BIT.
02900 JRST DVRBL4
00100 DF5: CAME A,COMMAV ;ARE THERE MORE DEFINITIONS ?
00200 JRST STATL1 ;NO.
00300 DFUNC: TRO FL,CSBRBT+SFOOBT ;ENTER FUNCTION DEFINING MODE.
00400 PUSHJ P,GETNAM ;GET FUNCTION NAME.
00500 EXP FUNBIT ;PARAMETER TO GETNAM.
00600 PUSH P,BUCTBL ;####$$%%$ A TEMPORARY KLUGE !!
00700 MOVE A,JOBFF ;GET FIRST FREE STORAGE LOC.
00800 HRRM A,(B) ;MAKE GOOD BITS WORD POINT THERE.
00900 HRLI A,600 ;MAKE A INTO A BYTE POINTER.
01000 PUSH P,A
01100 PUSH P,A
01200 IBP (P) ;THIS POINTER IS FOR PARAMETER DESCRIPTORS.
01300 HRLI A,400000+LRFXBT+RRFXBT ;NOW EMIT FIXUP TO THE
01400 ;LOCATION IN THE SYM. TABLE WHICH WILL
01500 MOVEI B,.FXBTS ;CONTAIN THE CALLING INSTR. FOR THE
01600 ; FUNCTION, SO IT CAN BE UPDATED AT
01700 PUSHJ P,EMICD ;LOAD TIME WITH THE RELOCATED ADDRESS OF THE FUNCTION.
01800 ADDI A,5 ;LEAVE ENOUGH ROOM FOR 22 PARAMETER
01900 HRRZM A,JOBFF ;DESCRIPTORS.
02000 TRNN FL,EXTFLG ;IS IT AN EXTERNAL FUNCTION ?
02100 SKIPA A,ILOC ;NO. ADDRESS IS IN ILOC.
02200 PUSHJ P,SYMSCH ;YES. FIND STARTING ADDRESS.
02300 TLO A,(<JSA RA,>) ;MAKE INTO A CALLING INSTR.
02400 MOVEM A,@-1(P) ;PLACE IN SYM. TABLE.
02500 LDB B,[POINT 4,A,17] ;GET THE RELOCATION BITS.
02600 TLZ A,17 ;TURN THEM OFF IN THE INSTRUCTION WORD.
02700 PUSHJ P,EMICD ;EMIT AS VALUE OF ABOVE FIXUP.
02800 PUSH P,[-1] ;INIT. THE PARAMETER COUNT.
02900 PUSHJ P,SCAN ;LOOK AT NEXT THING.
03000 CAME A,LPARV ;A ( ?
03100 JRST DFNOPR ;NO. THERE ARE NO PARAMETERS.
03200 DF2: PUSHJ P,SCAN ;SCAN A PARAMETER.
03300 CAME A,ARRV ;IS IT AN ARRAY NAME ?
03400 JRST DF2A ;NO.
03500 TRO FL,ARRFLG ;YUP. SET FLAG AND GET NAME OF
03600 JRST DF2 ;PARAM.
00100 DF2A: TLNE A,DF+NUMFLG
00200 ERROR (ILLEGAL FORMAL PARAMETER)
00300 AOS A,(P) ;INCREMENT PARAMETER COUNT.
00400 HRLI A,FPARBT!VRBLBT ;MAKE A INTO FORMAL PARAM. INDICATOR
00500 PUSHJ P,AENTER ; AND ENTER THE SYMBOL.
00600 MOVEI 2 ;PUT 'ORDINARY' FLAG IN THE PARAMETER
00700 TRZE FL,ARRFLG ;AN ARRAY NAME PARAM. ?
00800 MOVEI 1 ;YES. USE RIGHT DESCRIPTOR BIT.
00900 IDPB -1(P) ;DESCRIPTOR FOR THIS PARAM.
01000 PUSHJ P,SCAN
01100 CAMN A,COMMAV ;A COMMA ?
01200 JRST DF2 ;YES LOOK FOR MORE PARAMETERS.
01300 CAME A,RPARV ;IT BETTER BE A ).
01400 ERROR (MISSING RIGHT PAREN.)
01500 PUSHJ P,SCAN ;GET THE =.
01600 MOVEI B,0 ;FLAG END OF PARAMETER DESCRIPTORS.
01700 IDPB B,-1(P)
01800 DFNOPR: TRNE FL,EXTFLG ;IS THIS AN EXTERNAL FUNCTION ?
01900 JRST DF4 ;YES. LOOK FOR NO DEFINITION.
02000 CAME A,CTBL+"="
02100 ERROR (MISSING = IN FUNCTION DEFINITION)
02200 PUSHJ P,EMICDI ;LEAVE ROOM FOR THE JSA WORD.
02300 TRZ FL,SFOOBT ;LET SCANNER SEE FOO-SYMBOLS AGAIN.
02400 PUSHJ P,SEXPR ;SCAN AN EXPRESSION.
02500 DF4: PUSH P,A
02600 TRNE FL,EXTFLG ;AN EXTERNAL ?
02700 SKIPA E,[XWD SIACBT,0] ;YES. RESULT ALWAYS IN 0.
02800 PUSHJ P,GMURK1 ;GET IT OFF STACK.
02900 PUSHJ P,GG2 ;MAKE SURE ITS IN AN AC.
03000 IDPB A,-2(P) ;TELL UNIVERSE WHICH AC .
03100 AOS B,-1(P) ;ADJUST PARAMETER COUNT.
03200 IDPB B,-3(P) ;PUT IN SYM. TABLE.
03300 MOVEI A,RA ;EMIT RETURN INSTR.
03400 MOVSI C,(<JRA RA,(RA)>)
03500 TRNN FL,EXTFLG ;...UNLESS THIS IS AN EXTERNAL.
03600 PUSHJ P,EMINST
03700 AOS A,-2(P) ;FIND TOP OF PARAM. DESC. STRING.
03800 HRRZM A,JOBFF ;RESET FREE STORAGE.
03900 HRLM A,JOBSA
04000 POP P,A
04100 SUB P,[XWD 3,3] ;FORGET JUNK IN STACK.
04200 POP P,BUCTBL ;##$$%$# MORE OF THAT KLUGE !!!
04300 TRZ FL,CSBRBT+SFOOBT ;LEAVE FUNCTION DEFINING MODE.
04400 JRST DF5 ;ALL DONE.
00100 ;; MORE SYNTAX ANALYZER. COMPILE AN INSTRUMENT DEFINITION.
00200
00300 CINS: PUSHJ P,GETNAM ;GET NAME OF INSTRUMENT.
00400 EXP INSBIT ;PARAMETER TO GETNAM.
00500 AOS A,JOBFF ;GET PLACE FOR MORE GOOD BITS..
00600 SUBI A,1
00700 HRRM A,(B) ;MAKE RANDOM BITS WORD POINT THERE.
00800 HRLI A,RRFXBT ;RIGHT HALF REPLACEMENT TYPE FIXUP.
00900 MOVEI B,.FXBTS ;EMIT FIXUP TO RIGHT HALF FROM
01000 PUSHJ P,EMICD ;FIRST LOC. OF I-TIME CODE.
01100 HRLI A,LRFXBT+SWAPBT ;FIXUP TO LEFT HALF FROM FIRST LOC.
01200 PUSHJ P,EMCD ;OF R-TIME CODE.
01300 CINS5: PUSHJ P,SCAN
01400 CINS3: PUSHJ P,SMCS1 ;IGNORE SEMICOLON, IF ANY.
01500 CAMN A,ENDV ;IS IT AN END ?
01600 JRST CINSE ;YES.
01700 TLNN A,UGBIT ;IS IT A UNIT GENERATOR CALL ?
01800 JRST CINS4 ;NOT A UNIT GENERATOR.
01900 HRRZM A,CINST1# ;SAVE IT.
02000 PUSHJ P,SCAN ;PEEK AT NEXT THING.
02100 CAMN A,CTBL+"[" ;IS IT A [ ?
02200 JRST CUG1 ;YES. UNIT GEN. HAS CONTROLLED CALLING RATE.
02300 MOVEM A,SNCHR ;NO, IT'S PROBABLY THE (. PUT IT BACK WHERE SCAN WILL SEE IT AGAIN.
02400 PUSHJ P,CINS6 ;NOW COMPILE THE CALL ON THE UNIT GEN.
02500 JRST CINS5 ;BACK FOR MORE.
02600
02700 CINS6: MOVE A,CINST1 ;RECOVER POINTER FOR USE OF FUNCAL.
02800 PUSHJ P,FUNCAL ;COMPILE CALL ON THE UNIT GEN.
02900 MOVE B,VLOC ;GET LOC. FOR OUTPUT OF UNIT GEN.
03000 AOS C,UOPTR ;INCREMENT COUNT OF UNIT GENS.
03100 MOVEM B,UOTBL(C) ;ENTER OUTPUT LOC. IN TABLE.
03200 MOVE C,[MOVEM EMCDI] ;EMIT STORE INSTRUCTION TO
03300 PUSHJ P,EMINST ;PUT OUTPUT OF UNIT GEN. AWAY.
03400 PUSHJ P,EMDV ;MAKE ROOM IN VARIABLES AREA FOR IT.
03500 MOVE T,@CINST1 ;RETRIEVE PTR. TO RANDOM GOOD BITS.
03600 SKIPN A,-1(T) ;DOES UNIT GEN. HAVE I-TIME CODE?
03700 POPJ P, ;NO.
03800 PUSHJ P,EMIABS ;YUP. EMIT THE CALLING INSTR.
03900 HRRZ A,RLOC ;AS PARAMETER, GIVE IT A PTR. TO
04000 MOVEI B,RRELBT ;JUST AFTER THE MOVEM EMITTED
04100 PUSHJ P,EMICDI ;ABOVE.
04200 POPJ P,
00100 CINS4: PUSHJ P,STMT1 ;ITS NOT A UNIT GEN. CALL.
00200 JRST CINS3 ;NO
00300 CINSE: SETZM IARR1 ;YES. ZERO THINGS.
00400 MOVE [XWD IARR1,IARR1+1]
00500 BLT IARR3-1
00600 MOVE A,[POPJ P,] ;PUT RETURN INSTR. AT END OF
00700 MOVEI B,0 ;THE I-TIME CODE.
00800 PUSHJ P,EMICDI
00900 PUSHJ P,EMCDI ;ALSO THE R-TIME CODE.
01000 CINSR1: PUSHJ P,SCAN
01100 JRST STATL1
01200
01300 ;; IF THE NAME OF A UNIT GENERATOR IS FOLLOWED BY AN
01400 ;; EXPRESSION IN SQUARE BRACKETS, THE U.G. GETS CALLED ONLY
01500 ;; EVERY N TIME STEPS, WHERE N IS THE VALUE OF THE EXPRESSION.
01600 ;; N IS RECALCULATED EVERY TIME THE U.G. IS CALLED.
01700
01800 CUG1: MOVE C,[AOSGE EMCDI] ;INSTR. TO COUNT NO. OF TIME
01900 ;STEPS TO SKIP THIS UG.
02000 MOVE B,VLOC ;GRAB LOCATION IN VARIABLE AREA
02100 ;TO HOLD COUNT OF TIME STEPS TO SKIP.
02200 MOVEI A,0 ;NO AC FIELD, PLEASE.
02300 PUSHJ P,EMINST ;EMIT THE AOSGE JUST AHEAD OF THE CODE TO CALL THE U.G.
02400 MOVE C,[SETZM EMICDI] ;ALSO EMIT AN INSTR. TO THE I-TIME
02500 MOVE B,VLOC ;CODE TO INIT. THE COUNTER LOCATION TO 0
02600 ;(SO U.G. GETS CALLED FIRST TIME).
02700 PUSHJ P,EMINST
02800 PUSH P,RLOC ;SAVE R-TIME LOC. COUNTER (FOR LATER
02900 ;FIXUP TO JRST WE ARE ABOUT TO EMIT).
03000 PUSH P,VLOC ;ALSO VARIABLE LOC., FOR LATER LOADING
03100 ; OF THE STEPS-TO-SKIP COUNTER.
03200 PUSHJ P,EMDV ;MAKE A WORD FOR IT.
03300 MOVSI A,(<JRST>) ;NOW EMIT THE JUMP AROUND THE CALL OF
03400 PUSHJ P,EMCDI ;THE U.G. !!"" N.B.: B IS 0 HERE FROM CALL ON EMDV !!
03500 PUSHJ P,SEXPR ;NOW COMPILE THE EXPRESSION IN THE BRACKETS.
03600 CAME A,CTBL+"]" ;SHOULD BE FOLLOWED BY ONE...
03700 ERROR (MISSING ])
03800 MOVEI H,1 ;INDICATE THAT WE ARE WORKING WITH R-TIME CODE...
03900 PUSHJ P,GMURK1 ;..AND GET EXPR OFF OPERAND STACK.
04000 PUSHJ P,GG2 ;NOW GET IT INTO AN AC.
04100 MOVSI C,(<FIX>) ;EMIT INSTR. TO FIX VALUE OF EXPRESSION.
04200 MOVEI B,233000 ;MAGIC NO. FOR ADDRESS OF FIX, HO HO.
04300 PUSHJ P,EMINST
04400 POP P,B ;GET LOCATION IN VARIABLE AREA OF THE STEPS-TO-SKIP COUNTER.
04500 MOVSI C,(<MOVNM>) ;AND EMIT INSTR. TO STORE NEGATIVE OF COUNT THERE.
04600 PUSHJ P,EMINST
04700 PUSHJ P,CINS6 ;NOW COMPILE CALL ON UNIT GENERATOR.
04800 POP P,A ;RECOVER LOC. OF THE JRST UNDER THE AOSGE.
04900 MOVEI B,.FXBTS ;EMIT FIXUP TO MAKE IT POINT HERE (I.E., AFTER
05000 PUSHJ P,EMCD ; END OF U.G. CALL).
05100 JRST CINS5 ;ALL DONE.
00100 ;; THE WONDERFUL, WINNING LOADER.
00200
00300 R←←1
00400 I←←2
00500 V←←3
00600
00700 LOADER: MOVE R,JOBFF ;R-TIME CODE RELOCATION CONST.
00800 HRRZ I,RLOC ;
00900 ADD I,R ;I-TIME CONST.
01000 HRRZ V,ILOC
01100 ADD V,I ;VARIABLE RELOC. CONST.
01200 MOVE T3,V
01300 ADD T3,VLOC ;PROGRAM BREAK.
01400 HRRZM T3,JOBFF
01500 HRLM T3,JOBSA ;MAKE SURE IT TAKES.
01600 HRL A,R ;ZERO THE PROGRAM AREA.
01700 HRRI A,1(R)
01800 SETZM (R)
01900 BLT A,-1(T3)
02000 MOVEI H,0 ;START WITH R-TIME CODE.
02100 LD1: ADDI H,1 ;GO TO NEXT CHAIN OF BUFFERS.
02200 CAILE H,3 ;ALL DONE ?
02300 POPJ P, ;YES.
02400 PUSH P,[LDL1] ;FAKE UP A RETURN TO LDL1.
02500 MOVE C,(H) ;INIT. THE CURRENT LOC. COUNTER.
02600 SKIPA F,FCBUF-1(H) ;PTR. TO FIRST BUF. OF CHAIN.
02700 LD2: HRRZ F,(F) ;PTR. TO NEXT BUF. OF CHAIN.
02800 HRRZ E,F ;SET UP BYTE PTR. TO RELOC. BITS.
02900 HRLI E,200
03000 HRRZI D,LOBUFS/12+2(F) ;PTR. TO DATA IN BUF.
03100 HRLI D,-<LOBUFS-LOBUFS/12-2> ;WORD COUNT.
03200 LDGW: AOBJP D,LD2 ;WORD COUNT EXHAUSTED ?
03300 MOVE (D) ;NO. PICK UP NEXT DATA WORD.
03400 ILDB A,E ;FIRST 2 REL. BITS.
03500 ILDB B,E ;LAST 2.
03600 POPJ P,
03700 LDL: PUSHJ P,LDGW ;GET NEXT WORD FROM BUFFER.
03800 LDL1: JUMPE A,LDF1 ;NO REL. GIVEN; MAY BE A FIXUP.
03900 JUMPE B,LDRST ;IF NEITHER HALF, THEN IT'S A RESET.
04000 PUSH P,CLD3 ;ANOTHER FAKE RETURN ADDRESS.
04100 LDRL1: TRNE B,1 ;RELOCATE RIGHT HALF ?
04200 ADD (A) ;YES.
04300 TRNN B,2 ;LEFT HALF ?
04400 POPJ P, ;NO.
04500 MOVSS (A)
04600 ADD (A)
04700 MOVSS (A)
04800 POPJ P,
04900 LD3: ADDM (C) ;PUT IN CORE.
05000 CLDL: AOJA C,LDL ;GET ANOTHER.
00100 ;; MORE LOADER (BUT NOT MUCH MORE, YOU WILL NOTICE !).
00200
00300 LDF1:
00400 CLD3: JUMPE B,LD3 ;PERHAPS NOT A FIXUP.
00500 JUMPE LD1 ;IT MIGHT EVEN BE AN END MARK.
00600 LDB T3,[POINT 2,0,15] ;A FIXUP. GET REL. BITS FOR PTR.
00700 DPB T3,[POINT 5,0,17]
00800 PUSH P,0
00900 JUMPG LDF2 ;IS VALUE OF FIXUP TO BE FOUND IN BUFFER ?
01000 PUSHJ P,LDGW ;YES. GET IT.
01100 PUSHJ P,LDRL1 ;PERFORM ANY INDICATED RELOCATION ON IT.
01200 SKIPA T3,0 ;MOVE RELOCATED VALUE INTO T3.
01300 LDF2: MOVE T3,C ;VALUE IS CURRENT LOCATION.
01400 POP P,0 ;BRING BACK THE POINTER WORD.
01500 TLNE SWAPBT ;SHOULD WE EXCHANGE HALVES OF THE VALUE ?
01600 MOVSS T3 ;YES.
01700 TLNE RRFXBT ;SHOULD WE REPLACE THE RIGHT HALF OF THE LOCATION ?
01800 HRRM T3,@0 ;YES. SEE THE POINTER RELOCATION HAPPEN AUTOMATICALLY !!
01900 TLNE LRFXBT ;REPLACE THE LEFT HALF ?
02000 HLLM T3,@0 ;YES.
02100 TLNN LRFXBT+RRFXBT ;IF NEITHER HALF REPLACED, THEN
02200 ADDM T3,@0 ;IT'S AN ADDITIVE FIXUP.
02300 JRST LDL ;BACK TO MAIN LOOP.
02400
02500 LDRST: HALT ;THE FEATURE YOU HAVE REQUESTED ...
02600
02700
00100 DARR: PUSH P,[0] ;DEFINE SOME ARRAYS.
00200 DARR1: PUSHJ P,GETNAM ;SCAN NAME.
00300 XWD DF,SWVBT ;TYPE PARAMETER TO GETNAM.
00400 PUSH P,A ;STACK PTR. TO ENTRY.
00500 PUSHJ P,SCAN ;LOOK FOR COMMA.
00600 CAMN A,COMMAV ;IS IT ONE ?
00700 JRST DARR1 ;YES. GET MORE NAMES.
00800 CAME A,LPARV ;NO. SHOULD BE A (.
00900 ERROR(MISSING LEFT PAREN.)
01000 PUSHJ P,SCAN ;GET THE DIMENSION.
01100 TLNN A,NUMFLG ;MAKE SURE IT'S A NUMBER.
01200 ERROR(IMPROPER DIMENSION)
01300 MOVE B,(A) ;GET VALUE.
01400 TLNN A,FIXFLG ;IS IT FLOATING ?
01500 FIX B,233000
01600 ;***********↑↑↑↑↑↑↑
01700 DARR3: AOS JOBFF ;GET FREE STORAGE PTR.
01800 POP P,T ;PTR. TO NAME IN TABLE...
01900 JUMPE T,DARR2 ;UNLESS ITS THE MARK.
02000 JUMPG T,DARR4 ;WAS IT PREVIOUSLY DEFINED ?
02100 HRRZ T1,(T) ;YES. GET ITS BASE ADDRESS.
02200 CAMG B,-1(T1) ;IS NEW DIMENSION > OLD ?
02300 JRST DARR3 ;NO. LEAVE OLD DEFINITION ALONE.
02400 DARR4: AOS A,JOBFF ;INCREMENT FREE STG. PTR. AGAIN.
02500 HRRM A,(T) ;PUT IN SYM. TABLE.
02600 MOVEM B,-1(A) ;PUT DIMENSION IN -1TH ELEMENT.
02700 HRLI A,INSXR ;PUT GOOD INDEX FIELD IN A...
02800 MOVEM A,-2(A) ;PUT PTR. TO ARRAY WITH INDEX IN AR[-2]
02900 ADDM B,JOBFF ;INCREMENT IT.
03000 JRST DARR3 ;TRY FOR ANOTHER.
03100 DARR2: PUSHJ P,SCAN ;GET THE ).
03200 CAME A,RPARV
03300 ERROR(MISSING RIGHT PAREN.)
03400 PUSHJ P,SCAN
03500 CAMN A,COMMAV ;A COMMA ?
03600 JRST DARR ;YES. START OVER AGAIN.
03700 HRRZ JOBSYM ;LET'S FIND OUT IF WE'VE LOST...
03800 CAMG JOBFF ;IS TOP STILL ABOVE BOTTOM ?
03900 ERROR(STORAGE IS FULL)
04000 HRRZ JOBFF
04100 HRLM JOBSA
04200 JRST STATL1
00100 ; HERE IS THE OUTER LOOP OF THE WHOLE SYSTEM.
00200
00300 CHOWN1: PUSHJ P,INTER1 ;INTERPRET STATEMENT.
00400 SCHOWN: PUSHJ P,SMSC1 ;GET FIRST NON-SEMICOLON.
00500 CHOWN: CAMN A,PLAYV ;IS IT A 'PLAY' SECTION ?
00600 JRST PLAY1 ;YES.
00700 CAMN A,ALTV ;IS IT AN ALT MODE ?
00800 JRST COMMND ;YES. A COMMAND FOLLOWS.
00900 CAME A, COMPV ;A 'COMPILE' SECTION ?
01000 JRST CHOWN1 ;NO. JUST A STATEMENT.
01100 PUSHJ P,SCOMP ;INIT. THE COMPILER.
01200 PUSHJ P,SSTATL ;COMPILE A STATEMENT LIST.
01300 PUSHJ P,LOADER ;LOAD THE CODE.
01400 JRST SCHOWN ;DONE WITH THAT SECTION.
01500
01600 PLAY1: PUSHJ P,GSBUF ;WE'RE GOING TO PLAY; GET SAMPLE BUFFER.
01700 AOS SBCNT
01800 PLAY1A: SETZM TIME# ;T←0.
01900 SETZM RQPTR# ;RUN QUEUE IS EMPTY.
02000 SETZM MAXSMP# ;INIT. THE MAXIMUM SAMPLE REMEMBERER.
02100 PLAY2: PUSHJ P,SMSC1 ;SCAN A NON-SEMICOLON.
02200 CAME A,FINV ;A 'FINISH ' ?
02300 CAMN A,PLAYV ;... OR A 'PLAY' ?
02400 JRST PTERM ;YES. END OF SECTION.
02500 TLNE A,INSBIT ;AN INSTRUMENT NAME ?
02600 JRST PINS ;YES. A NOTE STATEMENT.
02700 PUSH P,[EXP PLAY2] ;NO. INTERPRET THE STATEMENT.
02800 INTER1: CAME A,INSV
02900 CAMN A,FUNV
03000 ERROR (ILLEGAL 'PLAY' STATEMENT)
03100 PUSHJ P,SCOMPA ;IT MUST BE A RANDOM STATEMENT.
03200 ;PREPARE TO INTERPRET IT BY INITIALIZING
03300 ;THE COMPILER.
03400 PUSHJ P,STAT ;COMPILE THE STATEMENT.
03500
03600 INTERP: MOVE A,[JRST INTER2] ;PREPARE TO EXECUTE TEMPORARY
03700 MOVEI B,0 ;CODE (I.E,RUN IN INTERPRET MODE).
03800 PUSHJ P,EMICDI ;EMIT RETURN INSTR. AT END OF CODE.
03900 PUSHJ P,ENDP1 ;CLEAN UP COMPILER.
04000 PUSH P,JOBFF ;SAVE FREE STG. PTR.
04100 PUSHJ P,LOADER ;LOAD THE TEMPORARY CODE.
04200 MOVEM P,PSV1# ;SAVE IT.
04300 MOVEM FL,FLSV1#
04400 MOVE 17,P ;PTR. FOR (UGH! BLETCH!) FOOTRAN PGMS.
04500 JRST @(P) ;EXECUTE IT.
04600 INTER2: MOVE P,PSV1 ;RESTORE PUSHDOWN POINTER.
04700 MOVE FL,FLSV1
04800 POP P,0 ;RETRIEVE OLD STG. PTR.
04900 HRRZM JOBFF ;FLUSH THE TEMP. CODE.
05000 HRLM JOBSA ;(IT HAS TO GO HERE TOO.)
05100 POPJ P, ;LOOK, MA, I'M AN INTERPRETER !!
05200
00100 ;THIS CODE READS A NOTE STATEMENT, INITIALIZES THE
00200 ; INSTRUMENT, AND GETS IT TURNED ON AT THE RIGHT TIME.
00300
00400 PINS: MOVE A,(A) ;GET STARTING ADDRESSES FOR INSTRUMENT.
00500 PUSH P,(A) ;SAVE THEM.
00600 MOVEI PBASE ;PREPARE TO FILL THE P ARRAY WITH
00700 MOVEM PPTR1# ;THE PARAMETERS TO THE INSTR.
00800 PUSHJ P,SCOMPA ;INIT. COMPLR. FOR POSSIBLE EXPRESSIONS.
00900 MOVE NCHNS ;GET NO. OF OUTPUT CHANNELS.
01000 TLNE -1 ;IS IT FLOATING ?
01100 FIX 233000
01200 ;**********↑↑↑↑↑↑↑↑↑
01300 PINS2: MOVEM NCHNS
01400 PUSH P,NUMBUC ;SAVE CURRENT STATE OF NUMBER
01500 PUSH P,JOBFF ;BUCKET AND CORE TOP.
01600 JRST PINSL ;INIT. THE COMPILER.
01700
01800
01900 PINSL1: CAMN A,COMMAV ;OPTIONAL COMMA BETWEEN PARAMS...
02000 PINSL: PUSHJ P,SCAN
02100 AOS PPTR1 ;INCREMENT P-ARRAY POINTER.
02200 CAMN A,COMMAV ;A COMMA HERE MEANS MISSING
02300 JRST PINSL ;PARAM., SO DON'T CHANGE.
02400 CAMN A,SEMICV ;SEMICOLON ?
02500 JRST PINSB ;YES, END OF PARAMETERS.
02600 PUSHJ P,EXPR ;PARAMETER MAY BE EXPRESSION.
02700 PUSHJ P,GPONDER ;GET OPERAND POINTER FOR THE EXPR...
02800 TLNE T,SIACBT ;IS VALUE OF EXPR AN AC SYMBOL ?
02900 JRST PINS1 ;YES. IT HAS TO BE CALCULATED.
03000 MOVE C,(T) ;PICK UP ITS VALUE.
03100 MOVEM C,@PPTR1 ; SO PUT ITS VALUE IN P-ARRAY NOW.
03200 JRST PINSL1
03300 PINS1: PUSH P,A ;EXPR. GENERATED SOME CODE, EVIDENTLY.
03400 MOVE A,T ;EMIT AN INSTRUCTION TO STORE THE
03500 MOVE B,PPTR1 ;RESULTANT VALUE IN THE P-ARRAY.
03600 MOVE C,[MOVEM EMICDI]
03700 PUSHJ P,EMINST ;THE CODE WILL GET EXECUTED
03800 PUSHJ P,INTERP ; RIGHT NOW.
03900 PUSHJ P,SCOMPA
04000 POP P,A
04100 JRST PINSL1 ;BACK FOR MORE PARAMS.
00100 ;; MORE OF PINS.
00200
00300 PINSB: POP OSP,JOBSYM ;FLUSH COMPLR. OUTPUT BUFFERS.
00400 POP P,0 ;RECOVER OLD CORE TOP.
00500 MOVEM JOBFF ;RESET THINGS TO FORGET
00600 HRLM JOBSA ;ABOUT THE NUMBERS WE DEFINED WHILE
00700 POP P,NUMBUC ;SCANNING NOTE PARAMETERS.
00800 MOVE A,SRATE ;GET NO. OF SAMPLES/SEC.
00900 FDVR A,TIMESC ;DIVIDE BY BEATS/SEC.
01000 MOVE B,PBASE+1 ;GET STARTING TIME FOR NOTE.
01100 FMPR B,A ;CONVERT TO SAMPLES.
01200 FADR B,[0.5]
01300 FIX B,233000
01400 ;***********↑↑↑↑↑↑↑↑↑
01500 MOVEM B,RQ1 ;PLACE AT BOTTOM OF RUN QUEUE.
01600 FMPR A,PBASE+2 ;GET DURATION OF NOTE IN SAMPLES.
01700 FADR A,[0.5]
01800 FIX A,233000
01900 ;***********↑↑↑↑↑↑↑↑↑
02000 ADD A,B ;CALC. ENDING TIME OF NOTE.
02100 PUSH P,A ;SAVE SAME.
02200 PUSHJ P,PLAYIT ;PLAY UP TO STARTING TIME OF NOTE.
02300 PLYON: AOS A,RQPTR ;NOW TURN INSTRUMENT ON.
02400 POP P,RQ1(A) ;PUT ENDING TIME IN RUNQUEUE, COL. ONE.
02500 POP P,T ;GET STARTING ADDR. OF INSTRUMENT.
02600 HLRZM T,RQ2(A) ;PLACE IN RUN QUEUE, COL. TWO.
02700 PUSHJ P,(T) ;EXECUTE THE I-TIME CODE.
02800 JRST PLAY2 ;BACK FOR MORE NOTE STATEMENTS.
02900
03000 PTERM: PUSH P,A ;HERE AT A 'PLAY' OR 'FINISH'.
03100 MOVSI 200000
03200 MOVEM RQ1 ;SET UP FAKE STARTING TIME.
03300 PUSHJ P,PLAYIT ;FLUSH THE RUN QUEUE.
03400 POP P,A
03500 CAMN A,PLAYV ;WAS IT A 'PLAY' THAT WE SAW ?
03600 JRST PLAY1A ;YES. START NEW SECTION.
03700 PUSHJ P,OSBUF ;NO, A 'FINISH'. EMPTY THE
03800 JRST SCHOWN ;SAMPLE BUFFER AND START OVER.
00100 ;; THIS ROUTINE GENERATES SAMPLES BY CALLING THE
00200 ;; INSTRUMENTS IN THE RUN QUEUE UNTIL IT IS TIME
00300 ;; TO TURN ON THE INSTRUMENT WHOSE STARTING TIME IS
00400 ;; IN THE ZEROTH LOCATION OF THE QUEUE, WHEN IT RETURNS.
00500 ;; INSTRUMENTS ARE TURNED OFF AS REQUIRED.
00600
00700 PLAYIT: MOVE A,RQPTR ;SEARCH FOR EARLIEST TIME IN QUEUE.
00800 PLYT2: MOVEM A,PTMP# ;SAVE ITS LOCATION.
00900 SKIPA H,RQ1(A) ;PICK IT UP.
01000 CAMG H,RQ1(A) ;A NEW MINIMUM ?
01100 SOJGE A,.-1 ;NO.
01200 JUMPGE A,PLYT2 ;YES.
01300 PLYT1: CAMN H,[XWD 200000,0] ;MIN. FOUND. IS IT THE TERMINATION
01400 POPJ P, ; MARK ? IF YES, THEN RETURN.
01500 SUB H,TIME ;IT'S NOT . CALC. DISTANCE IN FUTURE.
01600 JUMPLE H,PLYT3 ;IF NOT IN FUTURE, FORGET IT.
01700 ADDM H,TIME ;MOVE TIME TO NEW VALUE.
01800 PLYT4: SKIPE OSP,RQPTR ;CYCLE THRU RUNNING INSTRS., IF ANY.
01900 PUSHJ P,@RQ2(OSP) ;CALL AN INSTR.
02000 SOJG OSP,.-1 ;CALL THEM ALL.
02100 MOVEI F,1 ;START WITH CHANNEL 1.
02200 PLYT5: SOSG SBCNT ;COUNT SAMPLE BUFFER COUNTER.
02300 PUSHJ P,FSBUF ;FLUSH FULL BUFFER.
02400 MOVEI B,0 ;PICK UP NEXT CHANNEL'S SAMPLE, AND
02500 EXCH B,OUTA-1(F) ; ZERO THE LOCATION.
02600 FAD B,[0.5] ;ROUND TO NEAREST INTEGER.
02700 FIX B,233000 ;A. KOTOK SHOULD HAVE DONE THIS.
02800 ;************↑↑↑↑↑↑↑↑
02900 MOVM A,B ;GET MAGNITUDE...
03000 CAMLE A,MAXSMP ;IS THIS SAMPLE THE BIGGEST YET ?
03100 MOVEM A,MAXSMP ;YUP.
03200 IDPB B,SBPTR ;PLACE IT IN SAMPLE BUFFER.
03300 CAMGE F,NCHNS ;LAST CHANNEL ?
03400 AOJA F,PLYT5 ;NO. GET OTHER CHANNELS.
03500 SOJG H,PLYT4 ;GENERATE REST OF SAMPLES.
03600
03700 PLYT3: SKIPG A,PTMP ;GET PTR. TO NEXT INSTR. OFF OR ON.
03800 POPJ P, ;TIME TO TURN ONE ON.
03900 SOS B,RQPTR ;REMOVE INSTR. FROM QUEUE.
04000 MOVE RQ1+1(B) ;MOVE TOP ENTRY DOWN INTO VACANT
04100 MOVEM RQ1(A) ;SPOT.
04200 MOVE RQ2+1(B)
04300 MOVEM RQ2(A)
04400 JRST PLAYIT ;GO PLAY TILL NEXT EVENT.
04500
00100 ;; RANDOM ROUTINES TO HANDLE THE SAMPLE OUTPUT BUFFER.
00200
00300 GSBUF: HRRZ T,JOBSYM ;GET A SAMPLE BUFFER.
00400 SUB T,JOBFF ;HOW MUCH ROOM IS LEFT ?
00500 SUBI T,4*LOBUFS ;(ALLOWING ROOM FOR CODE BUFFERS)
00600 SKIPN BIGBIT ;SETS LSBUF TO 1024 IF EITHER BIGBIT OR RCDFLG!
00700 SKIPE RCDFLG
00800 SKIPA
00900 JRST GSBUF1 ;1023 IS FOR DEFERRED LONGPLAY
01000 CAIGE T,=1024 ;1024 IS FOR IMMEDIATE LONGPLAY WITH 'PLAY'
01100 ERROR (ADD 1K OF CORE!)
01200 MOVEI T,=1023
01300 SKIPGE RCDFLG ;IS IT POSITIVE OR ZERO?
01400 MOVEI T,=1024 ;NO, RCDFLG←-1; IS FOR IMMEDIATE LONGPLAY
01500 GSBUF1: MOVEM T,LSBUF ;PUT AWAY.
01600 MOVNS T
01700 PUSHJ P,GFS ;GRAB ENOUGH FREE STORAGE...
01800 HRRZM T,SBBOTT# ;SAVE PTR. TO BUFFER.
01900 FSBUF2: HRLI T,441400 ;MAKE BYTE POINTER.
02000 SKIPE BIGBIT ;IS IT 18 BIT?
02100 HRLI T,442200 ;YES. RESET BYTE SIZE
02200 MOVEM T,SBPTR# ;
02300 MOVE T,LSBUF ;GET LENGTH OF BUFFER.
02400 ASH T,1 ;SAMPLE CT = LSBUF *2 FOR 18 BIT
02500 SKIPN BIGBIT ;IS IT 18 BIT?
02600 ADD T,LSBUF ;NO, MAKE * 3.
02700 MOVEM T,SBCNT#
02800 POPJ P,
02900
03000 OSBUF: HRRZ LSBUF ;THROW OUT SAMPLE BUFFER...
03100 ADDM JOBSYM
03200 MOVEI 0
03300 SKIPA T,SBCNT
03400 IDPB 0,SBPTR
03500 SOJG T,.-1
03600 JRST FSBUF
03700
03800 SMPOUT: MOVE SBBOTT
03900 MOVEM IBOTT
04000 ; MAR 16,71 MOVE BIGBIT
04100 ; MAR 16,71 MOVEM IBIT#
04200 JSA 16, SMPLS ;CALL WRITING ROUTINE
04300 JUMP LSBUF
04400 JUMP SBCNT
04500 IBOTT: 0
04600 JUMP MAXSMP
04700 ; MAR 16,71 JUMP IBIT
04800 JUMP BIGBIT
04900 JUMP RCDFLG ;RCDFLG←-1 WRITES ONE LONG .DMD FILE 6/71
05000 SKIPN BIGBIT
05100 SKIPE RCDFLG ;RCDFLG ON?
05200 SKIPE DOPLAY ;PLAY ANYWAY?
05300 JRST FSBUF1 ;GO TO PLAY
05400 JRST FSBF2A ;DOESN'T PLAY
05500
05600
05700 FSBUF: SKIPN BIGBIT
05800 SKIPE RCDFLG# ;OUTPUT TO DISC?
05900 JRST SMPOUT
06000 FSBUF1: HRR SBBOTT ;CALCULATE NEGATIVE WORD COUNT.
06100 SUB SBPTR
06200 SUBI 1 ;PREVENT 0 WORD COUNTS.
06300 HRRZ T,SBBOTT ;GET BOTTOM OF BUFFER....
06400 HRLI -1(T) ; MINUS ONE.
06500 MOVSM OUTWC ;PUT IOWD IN RIGHT PLACE.
06600 ;*** SEE EXPORT VERSION AT THIS POINT FOR OUTPUT *******************
06700 PUSHJ P,FSBF1
06800 JRST FSBF2
06900 FSBF1: MOVE NCHNS ;NO. OF OUTPUT CHANNELS.
07000 TLNE -1
07100 FIX 233000
07200 ;**************↑↑↑↑↑↑↑
07300 FSBF3: SUBI 1
07400 DPB [POINT 2,OUTBIT,26] ;STEREO OR MONO MODE.
07500 MOVM SPEED
07600 TLNE -1 ;FIX IF NECESSARY.
07700 FIX 233000
07800 ;*********↑↑↑↑↑↑↑↑↑
07900 FSBF4: DPB [POINT 3,OUTBIT,32]
08000 L1: INIT ADCHN,17
08100 SIXBIT /AD/
08200 0
08300 ERROR (A-D UNAVAILABLE.)
08400 POPJ P,
08500
08600 XGP: MOVSI 'XGP' ;TO AVOID XGP CONFILICT
08700 DEVUSE 0,
08800 HLRZ 0,0
08900 CAIN 400000
09000 POPJ P,
09100 INIT 16,17
09200 SIXBIT .XGP.
09300 0
09400 JRST XGP ;was JRA 16,2(16)
09500 POPJ P,
09600 FSBF2: PUSHJ P,XGP ;GO INIT THE XGP
09700 OUTPUT ADCHN,OUTWC ;EMPTY THE BUFFER.
09800 RELEAS ADCHN,
09900 RELEASE 16,
10000 FSBF2A: MOVE T,SBBOTT ;NOW SET UP POINTERS AGAIN.
10100 JRST FSBUF2
10200
10300 OUTWC: 0
10400 3650 ;MAGIC BITS FOR 136.
10500 OUTBIT: 4000 ;BITS FOR A-D.
10600 BLOCK 2
00100 ;; ERROR HANDLING(?) ROUTINES.
00200
00300 ERR1: 0 ;HERE FROM UUO TRAP.
00400 TLNE FL,ERRFLG ;IN ERROR SKIPPING MODE ?
00500 JRST 2,@ERR1 ;YES.
00600 MOVEM 17,ERSVAC+17 ;NO. SAVE ACS.
00700 MOVEI 17,ERSVAC
00800 BLT 17,ERSVAC+16
00900 JSR ERR2 ;PRINT MESSAGE.
01000 MOVSI 17,ERSVAC ;RESTORE AC'S.
01100 BLT 17,17
01200 ERRX: TLO FL,ERRFLG ;ENTER ERROR-SKIPPING MODE.
01300 RELEAS TTY,0
01400 RELEAS DT,0
01500 PUSHJ P,SETUP1
01600 JRST GOB
01700 JRST 2,@ERR1 ;TRY TO CONTINUE (HO, HO.).
01800
01900 ERSVAC: BLOCK 20
02000
02100 ERR2: 0 ;ERROR MESSAGE PRINTER.
02200 HRRZI [ASCIZ /
02300 $$$ ERROR: /]
02400 JSR TXTOUT
02500 HRRZ 40
02600 JSR TXTOUT
02700 HRRZI [ASCIZ /
02800 /]
02900 JSR TXTOUT
03000 MOVE A,ISCP
03100 MOVE B,A
03200 MOVE C,B
03300 ERR2B: ILDB A
03400 CAIE 15
03500 JRST ERR2A
03600 MOVE C,B
03700 MOVE B,A
03800 ERR2A: CAME A,SCP
03900 JRST ERR2B
04000 JRST ERR2D
04100 ERR2C: SOSGE TOB+2
04200 OUTPUT TTY,0
04300 IDPB TOB+1
04400 ERR2D: ILDB C
04500 CAME C,SCP
04600 JRST ERR2C
04700 SKIPN SNCHR
04800 IDPB TOB+1
04900 OUTPUT TTY,0
05000 JRST @ERR2
05100
05200
00100
00200 SYMSCH: MOVEI T,6 ;LOOK UP EXTERNAL SYMBOL.
00300 MOVE [POINT 6,ACCUM,5] ;PREPARE TO CONVERT TO
00400 MOVEI B,0
00500 SYMS1: ILDB A,0 ;RADIX 50.
00600 JUMPE A,SYMS4
00700 CAIN A,16
00800 MOVEI A,73
00900 CAIG A,5
01000 ADDI A,70
01100 CAIGE A,32
01200 ADDI A,7
01300 IMULI B,50
01400 ADDI B,-26(A)
01500 SOJG T,SYMS1
01600 SYMS4: TLO B,40000
01700 MOVE A,116
01800 SYMS3: AOBJP A,SYMS2
01900 CAME B,-1(A)
02000 AOBJN A,SYMS3
02100 SYMS2: SKIPL A
02200 SKIPA A,[EXP NX]
02300 HRRZ A,(A)
02400 POPJ P,
02500
02600 NX: 0
02700 ERROR (MISSING EXTERNAL FUNCTION)
02800 JRST INTER2
02900
03000
03100 INTERNAL RDNUM,MESS,PNUM
03200
03300 EXTERNAL JOBDDT;
03400 PNUM: 0
03500 MOVE P,JOBFF
03600 SKIPGE A,@(RA)
03700 OUTCHR ["-"]
03800 MOVMS A
03900 PUSHJ P,DECPNT
04000 OUTPUT TTY,0
04100 JRA RA,1(RA)
00100 RDNUM: 0 ;NUMBER READER FOR FOOTRAN ROUTINES.
00200 MOVE P,JOBFF ;GET TEMP. PDL
00300 EXCH FL,FLSV1
00400 RDNUM1: TLO FL,SNUMF1
00500 PUSHJ P,SCAN
00600 CAMN A,MINV ;A MINUS SIGN ?
00700 TLOA FL,MINFLG ;YES. SET FLAG AND LOOP BACK.
00800 TLNN A,NUMFLG ;IT IS A NUMBER, ISN'T IT ?
00900 JRST RDNUM1 ;NO. IGNORE IT.
01000 TLZE FL,MINFLG ;YES. HAVE WE SEEN A MINUS LATELY ?
01100 MOVNS C ;YES.
01200 MOVEM C,@(RA) ;PUT VALUE INTO PARAMETER.
01300 EXCH FL,FLSV1
01400 JRA RA,1(RA) ;RETURN TO (UGH ! BLETCH !) FOOTRAN.
01500 MESS: 0 ;MESSAGE PRINTER FOR FOOTRAN ROUTINES.
01600 HRRZ (RA) ;GET LOC. OF MESSAGE.
01700 CALLI 3
01800 JRA RA,1(RA)
01900
02000 FOOPRT: 0
02100 MOVM A,@(RA)
02200 TLNE A,777000
02300 FIX A,233000
02400 ;**********↑↑↑↑↑↑↑↑↑↑↑
02500 PUSHJ P,DECPNT
02600 OUTPUT TTY,0
02700 JRST 1(RA)
02800
02900 COMMND: MOVEI [ASCII /$/]
03000 CALLI 3
03100 PUSHJ P,SCANNS ;GET COMMAND.
03200 JUMPL A,COMND1
03300 MOVE ACCUM
03400 MOVE 1,ACCUM+1
03500 LSHC 6
03600 CAMN [SIXBIT /RESET/]
03700 JRST REST1
03800 CAMN [SIXBIT /PRINT/]
03900 JRST CPNT ;A 'PRINT' COMMAND.
04000 CAMN [SIXBIT /P/]
04100 JRST CPLX
04200 CAMN [SIXBIT /DDT/]
04300 JRST @JOBDDT
04400 COMND1: MOVEI [ASCIZ /?? /]
04500 CALLI 3
04600 JRST SCHOWN
04700 CPLX: PUSHJ P,CGNUM ;GET FOLLOWING NUMBER, IF ANY.
04800 MOVEI T,1 ;NO NUMBER. TAKE AS 1.
04900 CPLAY:
05000 ; SKIPE DSKFLG ;DISK OUTPUT ?
05100 ; JRST DSKPLA ;YES.
05200 ;********* SEE EXPORT VERSION AT THIS POINT FOR OUTPUT *********
05300 PUSHJ P,FSBF1 ;SET UP FOR D-A OUTPUT.
05400 PUSHJ P,XGP
05500 OUTPUT ADCHN,OUTWC
05600 SOJG T,CPLAY ;REPEAT AS INDICATED BY ARGUMENT.
05700 RELEAS ADCHN,
05800 RELEASE 16,
05900 JRST SCHOWN
06000
00100 REST1: MOVEI TEMPSY
00200 MOVEM BUCTBL
00300 JRST GO
00400
00500 ;MORE COMMAND ROUTINES.
00600
00700 CPNT: PUSHJ P,SCOMPA ;INIT. THE COMPILER.
00800 PUSH OSP,[XWD VRBLBT,[XWD VRBLBT,CPNTX#]] ;PUT FAKE VARIABLE IN STACK.
00900 PUSHJ P,ASTMT1 ;COMPILE RIGHT PART OF AN ASSIGNENT STATEMENT.
01000 PUSHJ P,INTERP ;EXECUTE THE CODE.
01100 ;***** SEE EXPORT VERSION AT THIS POINT FOR OUTPUT *****************
01200 MOVM A,CPNTX ;GET ITS VALUE.
01300 TLNE A,377000 ;ASSUMING ITS >0, IS IT FLOATING?
01400 FIX A,233000
01500 ;***********↑↑↑↑↑↑↑↑↑
01600 CPNT2: PUSHJ P,DECPNT ;PRINT IT.
01700 OUTPUT TTY,0
01800 POP P,A ;GET THING WHICH TERMINATED EXPR. (LEFT ON STACK BY ASTMT1).
01900 CAMN A,SEMICV ;A SEMICOLON ?
02000 JRST SCHOWN ;YES. FORGET IT.
02100 JRST CHOWN ;NO. LOOK AT IT.
02200
02300
02400 CGNUM: TLO FL,SNUMF1 ;DONT PUT NO.'S IN TABLE.
02500 PUSHJ P,SCAN ;LOOK FOR (OPTIONAL) NUMERIC ARGUMENT.
02600 TLNN A,NUMFLG ;IS THERE ONE ?
02700 POPJ P, ;NO.
02800 MOVE T,C ;YES. GET VALUE.
02900 TLNN A,FIXFLG ;IS IT FLOATING ?
03000 FIX T,233000 ;NOT ANY MORE.
03100 ;*********↑↑↑↑↑↑↑↑↑↑↑
03200 CGNUM2: POP P,T1 ;GET RETURN ADDR.
03300 JRST 1(T1) ;SKIP ON RETURN.
03400 END GO